Для простых случаев существуют простые решения, поэтому если у Вас, оказывается, есть чистые, простые, базовые слова, без.? + * {} () [] \/и возможно более необычный sed-материал, можно передать список пар к sed-командному-файлу с sed:
sed -re 's,(^\\| \\|$),/,g;s/^/s/;s/$/g/' pairs.txt > pairs.sed
sed -f pairs.sed input > output
find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
Если больше чем один вызов du
требуется, потому что список файлов очень длинен, о нескольких общих количествах сообщат и потребность, которая будет суммирована.
du -ch public_html/images/*.jpg | grep total
20M total
дает мне общее использование моего .jpg
файлы в этом каталоге.
Для контакта с несколькими каталогами, необходимо было бы, вероятно, объединить это с find
так или иначе.
Вы могли бы найти примеры команды du полезными (это также включает find
)
Прежде всего, Вам нужны две вещи:
-c
опция к du
, сказать этому производить общий итог;**
(инструкции по активации) или find
(пример) или пересекать подкаталоги. du -ch -- **/*.jpg | tail -n 1
find
может возвратить ошибочные результаты.
– Eric Fournie
19.10.2016, 11:50
Ответы, которые были даны до сих пор, не учитывают, что список файлов, переданный из find в du, может быть настолько длинным, что поиск автоматически разбивает список на куски, в результате чего происходит многократное повторение всего
.
Вы можете либо grep total
(локаль!) и подвести итог вручную, либо использовать другую команду. AFAIK есть только два способа получить общую сумму (в килобайтах) всех найденных файлов:
find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'
Explanation
find . -тип f - имя '*.jpg' -print0
: Найдите все файлы с расширением jpg вне зависимости от регистра (т.е. *.jpg, *.JPG, *.Jpg...) и выведите их (нуль-терминированные).
xargs -r0 du -a
:
-r: Xargs вызовет команду даже без аргументов, что предотвращает -r. -0 означает null-terminated strings (не newline terminated)
awk '{sum+=$1}. END {print sum}'
: Суммируем размеры файлов, выводимых предыдущей командой
И для справки, другим способом будет
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-
Если список файлов слишком велик, чтобы его можно было передать в один вызов du -c
, то в системе GNU можно сделать:
find . -iname '*.jpg' -type f -printf '%b\t%D:%i\n' |
sort -u | cut -f1 | paste -sd+ - | bc
(размер, выраженный в количестве блоков по 512 байт). Как и du
, он пытается считать жесткие ссылки только один раз. Если вас не волнуют жесткие ссылки, вы можете упростить это до:
(printf 0; find . -iname '*.jpg' -type f -printf +%b) | bc
Если вы хотите, чтобы размер вместо диска использовался, замените %b
на %s
. Затем размер будет выражен в байтах
Упомянутые до сих пор решения неэффективны (exec стоит дорого) и требуют дополнительной ручной работы для суммирования, если список файлов длинный, или они не работают на Mac OS X. Следующее решение очень быстрое, работает на любой системе и выдает общий ответ в ГБ (уберите /1024, если хотите видеть общий ответ в МБ):
find . -iname "*.jpg" -ls |perl -lane '$t += $F[6]; print $t/1024/1024/1024 . "GB"''
Улучшение отличного ответа SHW, чтобы заставить его работать с любым языком, как Zbyszek уже указал в своем комментарии:
LC_ALL=C find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
du естественно обходит иерархию каталогов, а awk может выполнять фильтрацию, поэтому может быть достаточно чего-то вроде этого:
du -ak | awk 'BEGIN {sum=0} /\.jpg$/ {sum+=$1} END {print sum}'
Это работает без GNU.
Окончательный ответ:
{ find <DIR> -type f -name "*.<EXT>" -printf "%s+"; echo 0; } | bc
и даже более быстрая версия, не ограниченная ОЗУ, но требующая GNU AWK с поддержкой bignum:
find <DIR> -type f -name "*.<EXT>" -printf "%s\n" | gawk -M '{t+=$1}END{print t}'
Эта версия имеет следующие особенности:
find
, чтобы указать файлы, которые вы ищете find
выполняет простое сопоставление имен файлов с использованием подстановочных знаков 5,5K
, 176,7M
, ...)
| numfmt --to = si
Еще бы
ls -al <directory> | awk '{t+=$5}END{print t}}'
Предположим, вы ищете в одном каталоге. Если вы хотите посмотреть текущий каталог и под ним
ls -Ral <directory> | awk '{t+=$5}END{print t}}'
Это то, что сработало для меня.
find -type f -iname *.jpg -print0 | du -ch --files0-from=- | grep total$
Другой вариант использования stat вместо du
stat -L -c %s ** | awk '{s+=$1} END {printf "%.0f\n", s}'
См. ответ Жиля об использовании**
LC_ALL=POSIX
как префикс к всегда grep для общего количества как это:LC_ALL=POSIX find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
– Sven 27.06.2016, 08:48-name
, затем измените grep наgrep -P "\ttotal$"
или иначе это получит все файлы, заканчивающиеся "общим количеством" также. – thdoan 30.03.2017, 10:43bc
, таким образом, вот более портативное решение:find -name '*.jpg' -type f -exec du -bc {} + | grep total$ | cut -f1 | awk '{ total += $1 }; END { print total }'
– thdoan 30.03.2017, 10:55