Ответы:
Вы ищете трубы ( |
). Они представляют собой способ соединения нескольких команд и передачи вывода одной команды в качестве ввода другой. В этом случае вы хотите передать все имена файлов, которые вы найдете в качестве входных данных du
(который вычисляет размер). Однако, поскольку du
ожидаемые имена файлов и результаты find
являются просто списком текста (да, текст состоит из имен файлов, но du
не может этого знать, все, что он видит, это текст), вам нужно использовать что-то вроде того, xargs
который будет принимать каждый строка текста, обрабатывайте его как имя файла и передавайте его du
. Собрав все это вместе, мы получим:
find . -name "*.o" | xargs du -sch
Вы всегда должны цитировать шаблоны, которые вы даете find
(как я делал выше:) "*.o"
. Если вы этого не сделаете, оболочка развернет *.o
имена подходящих файлов в текущем каталоге. В этом случае это сработало только потому, что у вас не было подходящих файлов.
Эти -sch
флаги du
описаны в man du
:
-c, --total
produce a grand total
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-s, --summarize
display only a total for each argument
Обратите внимание, однако, что это не удастся для имен файлов, содержащих пробелы. Это почти наверняка не будет проблемой для объектных файлов, но в будущем, если вам также потребуется иметь дело с пробелами, используйте:
find . -name "*.o" -print0 | xargs -0 du -sch
В -print0
марке find
печать NULL разделенных строк и -0
марка xargs
принимает такие строки в качестве входных данных.
Кроме того, вы можете find
распечатать размеры сами, а затем сложить их:
find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'
Это также поможет обойти проблему, упомянутую @Serg в комментариях, где слишком много аргументов и команда разбита на отдельные команды.
Если вы используете bash
(вероятно), есть более простой способ:
shopt -s globstar
du -sch **/*.o
Команда shopt globstar
позволяет **
сопоставить все файлы и / или подкаталоги. После включения он **/*.o
будет сопоставлять все файлы (и каталоги), чье имя заканчивается .o
, поэтому мы можем передать его непосредственно du
.
Обратите внимание, что, в отличие от find
подхода, это не будет соответствовать скрытым файлам (те, чье имя начинается с a .
). Чтобы соответствовать этим, сделайте:
shopt -s dotglob globstar
du -sch **/*.o
shopt globstar
пример опускается -s
; Мне пришлось использовать shopt -s globstar
аналогично вашему второму примеру.
shopt OPTION
без -s
или или -u
(или другой параметр, см. help shopt
) просто печатает текущее значение OPTION. Вам нужно shopt -s OPTION
включить один и shopt -u OPTION
выключить его.
Используйте -exec
флаг для запуска du
команды ;
(значение для каждого файла)
find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}'
Пример вывода:
$ find . -name "*.txt" -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes
find
является рекурсивным - это означает, что он проходит через все подкаталоги. Если вы просто хотите получить общее количество всех *.o
файлов в текущем каталоге, просто выполните
du -b -c *.o
с Perl:
perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf
Размер всех не скрытых файлов PDF в текущем каталоге.
.o
файлы, и они могут находиться в подкаталогах. Вы также можете добавить }{
перед, print $sum
чтобы избежать вывода суммы для каждой итерации. Мы хотим только последний.
du
, и он будет производить несколькоtotal
строк. Вот пример: paste.ubuntu.com/23092752