Размер всех файлов определенного расширения в дереве каталогов


17

Я хочу узнать размер файла с расширением .o (объектный файл) в моей домашней папке.

Я могу найти все объектные файлы, используя

find . -name '*.o'

Как теперь я могу рассчитать общий размер этих файлов?

Ответы:


24

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

Есть небольшая проблема с первым. Существует такая вещь, как MAXARGS. Таким образом, будет несколько итераций du, и он будет производить несколько totalстрок. Вот пример: paste.ubuntu.com/23092752
Сергей Колодяжный

@ Серж правда. Я добавил еще один вариант, который избегает этого.
Тердон

Ваш первый shopt globstarпример опускается -s; Мне пришлось использовать shopt -s globstarаналогично вашему второму примеру.
CrazyPyro

@CrazyPyro d'oh! Извините, это была опечатка. Спасибо за указание на это. shopt OPTIONбез -sили или -u(или другой параметр, см. help shopt) просто печатает текущее значение OPTION. Вам нужно shopt -s OPTIONвключить один и shopt -u OPTIONвыключить его.
тердон

8

Используйте -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

0

с Perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

Размер всех не скрытых файлов PDF в текущем каталоге.


1
ОК, но ОП ищет .oфайлы, и они могут находиться в подкаталогах. Вы также можете добавить }{перед, print $sumчтобы избежать вывода суммы для каждой итерации. Мы хотим только последний.
Тердон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.