Предположим, есть каталог хранения изображений, скажем, ./photos/john_doe
в котором есть несколько подкаталогов, в которых находится много определенных файлов (скажем, *.jpg
). Как я могу рассчитать суммарный размер этих файлов под john_doe
веткой?
Я пытался du -hs ./photos/john_doe/*/*.jpg
, но это показывает только отдельные файлы. Кроме того, это отслеживает только первый уровень вложенности john_doe
каталога, вроде бы john_doe/june/
, но пропускает john_doe/june/outrageous/
.
Итак, как я могу пройти всю ветку, суммируя размер определенных файлов?
files
directory
directory-structure
size
mbaitoff
источник
источник
LC_ALL=POSIX
качестве префикса, чтобы всегда grep для общего количества, как это:LC_ALL=POSIX find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
-name
, то измените grep на,grep -P "\ttotal$"
иначе он будет захватывать все файлы, заканчивающиеся на «total».bc
find -name '*.jpg' -type f -exec du -bc {} + | grep total$ | cut -f1 | awk '{ total += $1 }; END { print total }'
дает мне общее использование моих
.jpg
файлов в этом каталоге.Чтобы иметь дело с несколькими каталогами, вам, вероятно, придется как-то комбинировать это
find
.Вы можете найти примеры команд du полезными (они также включают в себя
find
)источник
-R
варианта на man7.org/linux/man-pages/man1/du.1.html . И я не думаю, что рекурсивный вариант поможет в этом случае, потому что оболочка выполняет расширение glob перед передачей аргументовdu
.Прежде всего, вам нужно две вещи:
-c
возможностьdu
, чтобы сказать ему , чтобы произвести итог;**
( инструкции по активации ), либоfind
( пример ), либо для обхода подкаталогов.источник
find
может возвращать ошибочные результаты.du -ch -- ./{dir1,dir2}/*.jpg
илиdu -ch -- ./{prefix1*,prefix2*}.jpg
Argument list too long
ошибку при обработке около 300 тыс. Текстовых файлов.getconf ARG_MAX
. Если у вас есть больше, вам нужно будет обрабатывать файлы один за другим или периодически с циклом for.Окончательный ответ:
и даже более быстрая версия, не ограниченная оперативной памятью, но требующая GNU AWK с поддержкой bignum:
Эта версия имеет следующие особенности:
find
для указания файлов, которые вы ищетеfind
делает простой подстановочный знак соответствия имен файлов5.5K
,176.7M
...)| numfmt --to=si
источник
Ответы, данные до сих пор, не учитывают, что список файлов, передаваемый от find к du, может быть настолько длинным, что find автоматически разбивает список на куски, что приводит к множественным вхождениям
total
.Вы можете либо
grep total
(локаль!) Подвести итоги вручную, либо использовать другую команду. AFAIK Есть только два способа получить общую сумму (в килобайтах) всех файлов, найденных с помощью find:find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'
Объяснение
find . -type f -iname '*.jpg' -print0
: Найти все файлы с расширением jpg независимо от регистра (т. Е. * .Jpg, * .JPG, * .Jpg ...) и вывести их (с нулевым символом в конце).xargs -r0 du -a
: -r: Xargs будет вызывать команду даже без переданных аргументов, что предотвращает -r. -0 означает строки с нулевым символом в конце (не завершенный символом новой строки).awk '{sum+=$1} END {print sum}'
: Суммировать размеры файлов, выведенные предыдущей командойИ для справки, другой способ будет
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-
источник
du --file0-from
заняло больше времени, потому что вы запустили его первым (эффект кэширования)xargs
несколькоdu -a
, поэтому могут возникнуть расхождения при наличии жестких ссылок.Если список файлов слишком большой, чтобы его нельзя было передать за один вызов
du -c
, в системе GNU вы можете сделать:(размер выражается в количестве 512 байтных блоков). Как будто
du
он пытается сосчитать жесткие ссылки только один раз. Если вас не интересуют жесткие ссылки, вы можете упростить их до:Если вы хотите использовать размер вместо использования диска, замените его
%b
на%s
. Размер будет выражен в байтах.источник
-bash: bc: command not found
Centos - Linux 2.6.32-431.el6.x86_64bc
является необязательной командой POSIXУпомянутые решения пока неэффективны (exec стоит дорого) и требуют дополнительной ручной работы для суммирования, если список файлов длинный или они не работают в Mac OS X. Следующее решение очень быстрое, должно работать в любой системе, и выдает итоговый ответ в ГБ (удалите / 1024, если вы хотите увидеть сумму в МБ):
find . -iname "*.jpg" -ls |perl -lane '$t += $F[6]; print $t/1024/1024/1024 . " GB"'
источник
-iname
ни другое не-ls
является стандартным / переносимым, поэтому он не будет работать ни на одной системе . Это также не будет работать должным образом, если есть имена файлов или целевые ссылки, содержащие символы новой строки.Улучшение SHW - отличный ответ, чтобы он работал с любой локалью, как Zbyszek уже указал в своем комментарии:
источник
Естественно, du просматривает иерархию каталогов, и awk может выполнять фильтрацию, поэтому может быть достаточно чего-то подобного:
Это работает без GNU.
источник
stat
вызов файлов, которые не соответствуют искомому шаблону.