Як отримати команду find, щоб роздрукувати розмір файлу з ім'ям файлу?


106

Якщо я видаю команду find так:

$ find . -name *.ear

Він виводить:

./dir1/dir2/earFile1.ear
./dir1/dir2/earFile2.ear
./dir1/dir3/earFile1.ear

Що я хочу "надрукувати" в командному рядку, це ім'я та розмір:

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB

Відповіді:


109
find . -name '*.ear' -exec ls -lh {} \;

лише ч. додаткової відповіді на відповідь jer.drab.org. економить час, перетворюючись на МБ подумки;)


8
Ця версія буде виконувати "ls" процес для кожного файлу. Якщо у вас багато файлів (скажімо, понад тисячу), то краще оптимізувати це за допомогою: find . -name '*.ear' -exec ls -lh {} + \;(розширення GNU) або find . -name '*.ear' -print0 | xargs -0 ls -lh. Крім того, ви можете додати, -type fякщо вас цікавлять лише файли (або додати -dдо ls, якщо ви хочете, щоб самі каталоги були включені без їх вмісту).
ash108

2
Ваша відповідь не виключає каталогів, тому ви в кінцевому підсумку запустите ls і в каталогах, що, очевидно, не правильно.
Faheem Mitha

2
Це дійсно неефективний спосіб робити речі - і, на жаль, коментарі ash108 також не є ідеальними. Набагато краще використовувати параметр -printf, щоб знайти.
oskarpearson

Відповідь dmazzoni набагато ефективніше, тому що вона уникає fork + exec у кожному файлі (на 100 разів швидше на моїй машині). Мені довелося змінити% k на% s. @FaheemMitha: ви можете додавати параметри, як, наприклад, -type fпідраховувати лише звичайні файли.
Містер Фооз

@FaheemMitha просте рішення find . -name "*.ear" -type fдля файлів. -type dпрацює для каталогів.
anon58192932

111

Вам потрібно використовувати -exec або -printf. Printf працює так:

find . -name *.ear -printf "%p %k KB\n"

-exec є більш потужним і дозволяє виконувати довільні команди - тому ви можете використовувати версію 'ls' або 'wc' для друку імені файлу разом з іншою інформацією. 'man find' покаже вам доступні аргументи для printf, що може зробити набагато більше, ніж просто розмір файлів.

[edit] -printf не є офіційним стандартом POSIX, тому перевірте, чи підтримується він у вашій версії. Однак більшість сучасних систем використовуватимуть GNU find або аналогічно розширену версію, тому є хороший шанс, що вона буде реалізована.


Схоже, ваш приклад є більш точним, але я не можу отримати приклад для роботи над Solaris 10.
Брайан,

Я боюся, що пошук Solaris взагалі не підтримує -printf: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Ви можете встановити GNU find, якщо вас можуть турбувати, інакше вам потрібно використовувати exec або | як пропонують інші.
Лі Колдвелл

1
+1 Це здається більш чистим. Для форматування виводу я вважаю за краще додати columnкоманду. find . -name *.ear -printf "%p %k KB\n" | column -t
Амол

1
Ця відповідь є набагато правильнішим способом, ніж прийнята відповідь
грізно

2
-printfОпція не працює в OS X або. Дивіться stackoverflow.com/questions/752818/… .
abeboparebop

33

простим рішенням є використання параметра -ls у знаходженні:

find . -name \*.ear -ls

Це дає вам кожен запис у звичайному форматі "ls -l". Або для отримання конкретного результату, який, здається, ви шукаєте, це:

find . -name \*.ear -printf "%p\t%k KB\n"

Це дасть вам ім'я файлу з наступним розміром у КБ.


Навіть не знали про lsваріант, це повинно бути набагато вище в списку відповідей, ніж є.
Прометей

24

Використовуючи gnu find, я думаю, що саме цього ви хочете. Він знаходить усі реальні файли, а не каталоги (-тип f), і для кожного друкується ім'я файлу (% p), вкладка (\ t), розмір у кілобайтах (% k), суфікс "KB", а потім новий рядок (\ n).

find . -type f -printf '%p\t%k KB\n'

Якщо команда printf не форматує речі так, як вам потрібно, ви можете використовувати exec, а потім команду, яку потрібно виконати для кожного файлу. Використовуйте {} для імені файлу та завершіть команду крапкою з комою (;). На більшості оболонок всі три символи повинні бути уникнуті зворотним нахилом.

Ось просте рішення, яке знаходить і роздруковує їх за допомогою "ls -lh", яке покаже вам розмір у читаному для людини вигляді (k для кілобайт, M для мегабайт):

find . -type f -exec ls -lh \{\} \;

Як ще одна альтернатива, "wc -c" надрукує кількість символів (байтів) у файлі:

find . -type f -exec wc -c \{\} \;

+1 За винятком того, що -name '*.ear'у прикладах пропущено , це має бути відповідь №1. Він відповідає на запитання точно, пояснює значення синтаксису та дає безліч альтернатив.
OsakaWebbie

на це слід прийняти відповідь, оскільки він не запускає нову команду для кожного рядка, таким чином, це набагато швидше, ніж прийнятий на даний момент від shyam
jirislav

Дійсно, це має бути правильна відповідь. Крім того, find . -type f -printf '%k KB\t %p\n'тобто надрукувати розмір файлу спочатку, швидше за все, буде приємніше виводитись з точки зору форматування завдяки вирівнюванню.
myradio

8
find . -name '*.ear' -exec du -h {} \;

Це дає вам лише розмір файлів, а не всі непотрібні речі.


wcпрацює для цього просто краще, якщо вам потрібен розмір у байтах.
Алекс

4

Awk може виправити вихід, щоб дати лише те, що запитував запитувач. У моїй системі Solaris 10 знайдіть -ls друкує розмір у КБ як друге поле, так що:

% find . -name '*.ear' -ls | awk '{print $2, $11}'
5400 ./dir1/dir2/earFile2.ear
5400 ./dir1/dir2/earFile3.ear
5400 ./dir1/dir2/earFile1.ear

В іншому випадку використовуйте -exec ls -lh і виберіть поле розміру з виводу. Знову на Solaris 10:

% find . -name '*.ear' -exec ls -lh {} \; | awk '{print $5, $9}'
5.3M ./dir1/dir2/earFile2.ear
5.3M ./dir1/dir2/earFile3.ear
5.3M ./dir1/dir2/earFile1.ear

4

Чому б не використовувати du -a ? Напр

find . -name "*.ear" -exec du -a {} \;

Працює на Mac


3

Я боровся з цим на Mac OS X, де команда find не підтримує -printf.

Я знайшов рішення, яке, мабуть, покладається на "групу" для всіх файлів, які є "співробітниками", було ...

ls -l -R | sed 's/\(.*\)staff *\([0-9]*\)..............\(.*\)/\2 \3/'

Це розбиває ls довгий вихід на три лексеми

  1. матеріал перед текстом "персонал"
  2. розмір файлу
  3. ім'я файлу

А потім виводить лексеми 2 і 3, тобто вихід - це кількість байтів, а потім ім'я файлу

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php

1
Корисно знати .. Версія GNU findдоступна через домашню мову зbrew install findutils
mwfearnley

2

Це має отримати те, що ви шукаєте, включаючи форматування (тобто ім'я файлу спочатку та розмір згодом):

find . -type f -iname "*.ear" -exec du -ah {} \; | awk '{print $2"\t", $1}'

вибір вибірки (де я -iname "*.php"отримував певний результат):

./plugins/bat/class.bat.inc.php  20K
./plugins/quotas/class.quotas.inc.php    8.0K
./plugins/dmraid/class.dmraid.inc.php    8.0K
./plugins/updatenotifier/class.updatenotifier.inc.php    4.0K
./index.php      4.0K
./config.php     12K
./includes/mb/class.hwsensors.inc.php    8.0K

1

Ви можете спробувати це:

find. -name *.ear -exec du {} \;

Це дасть вам розмір у байтах. Але команда du також приймає параметри -k для KB і -m для MB. Це дасть вам такий вихід

5000  ./dir1/dir2/earFile1.ear
5400  ./dir1/dir2/earFile2.ear
5400  ./dir1/dir3/earFile1.ear



1

Спробуйте виконати наступні команди:

GNU stat:

find . -type f -name *.ear -exec stat -c "%n %s" {} ';'

BSD stat:

find . -type f -name *.ear -exec stat -f "%N %z" {} ';'

проте statне є стандартним, так duі wcможе бути кращим підходом:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'


0

Якщо вам потрібно отримати загальний розмір, ось пропозиція щодо сценарію

#!/bin/bash
totalSize=0

allSizes=`find . -type f -name *.ear -exec stat -c "%s" {} \;`

for fileSize in $allSizes; do
    totalSize=`echo "$(($totalSize+$fileSize))"`
done
echo "Total size is $totalSize bytes"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.