Ответы:
Вы ищете трубы ( |). Они представляют собой способ соединения нескольких команд и передачи вывода одной команды в качестве ввода другой. В этом случае вы хотите передать все имена файлов, которые вы найдете в качестве входных данных 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