Рассчитать размер файлов в оболочке

Я пытаюсь вычислить общий размер в байтах всех файлов (в дереве каталогов), соответствующих шаблону имени файла, просто используя оболочку. Вот что у меня есть на данный момент:

find -name * .undo -exec stat -c% s {} \; | awk '{total + = $ 1} END {print total}'

Есть ли более простой способ сделать это? Я чувствую, что должен быть простой переключатель du or find, который сделает это за меня, но я не могу его найти.

Чтобы быть ясным, я хочу суммировать файлы, соответствующие шаблону в любом месте дерева каталогов, что означает

du -bs * .undo

не будет работать, потому что он соответствует только файлам в текущем каталоге.

Ответов (15)

Решение

Пытаться:

find . -name "*.undo" -ls | awk '{total += $7} END {print total}'

В моей системе размер файла - седьмое поле find -ls вывода. Если ваш find … -ls результат отличается, отрегулируйте.

В этой версии использование существующей информации о каталоге (размер файла) и встроенная функция поиска ls должны быть эффективными, избегая создания процессов или ввода-вывода файлов.

find -name '*.undo' -print0 | du -hc --files0-from=- | tail -n 1

Соединенный с gerdemb х и взносов strager в. Использование du -cb должно отображать байты.

Как насчет этого простого.

find ./ -name *.undo | xargs wc

Я использую такую ​​команду du, чтобы получить только номер:

du file_list | awk '{s+=$1} END {print s}'

Или вы можете просто сделать это:

dir=$1

for file in $dir/* ; do

 length_file=`stat -c %s $file`
 echo "File $file has length $length_file"
 length_total=`expr $length_total + $length_file`

done

echo "Total length: $length_total ."

Где stat отображает статус файла или файловой системы. Аргумент -c означает использование указанного формата вместо формата по умолчанию, а последовательность форматов $ s позволяет отображать общий размер байтов.

expr 

Просто оценивает выражение.

Однострочный Perl:

find . -name "*.undo" -ls | perl -lane '$t += $F[6]; END{print $t}'

@F Массив AutoSplit начинается в индексе , $F[0] а AWK поля начинаются с $ 1, следовательно , $F[6] используется вместо AWK -х годов $7

du -c | awk '/./{line=$0} END {print $ 1}'

Думаю, версию с xargs можно улучшить (упростить) ls -1 * .undo | xargs туалет

Я тоже занимался этой проблемой (всего год спустя ...) - только что нашел эту страницу.

Я обнаружил, что работает (для меня) следующее:

find /mnt/iso -name *.avi -printf "%s\n" | paste -sd+ - | bc

Это вернет общий размер всех файлов .avi во всех подпапках ниже / mnt / iso.

Я должен отдать должное radoulov за команду paste - см. Эту страницу: Команда оболочки для суммирования целых чисел, по одному в строке?

Просто чтобы добавить - на случай, если папка соответствует поисковому запросу - это также хорошая идея для использования -type f в команде поиска.

Проверьте команду du (использование диска).

du -c *pattern*

Это напечатает итог в последней строке вывода.

find -name '*.undo' -exec wc -c {} + | tail -n 1

должен указывать фактическое общее количество байтов в файлах, если у вас не слишком много файлов (где «слишком много» будет действительно большим числом, вероятно, в тысячах). Или если вы просто хотите получить номер в одиночку,

find -name '*.undo' -exec wc -c {} + | tail -n 1 | cut -d' ' -f 1

Python является частью большинства дистрибутивов Linux.

import os
import fnmatch
size= 0
for path, dirs, files in os.walk( '.' ):
    for f in files:
        if fnmatch.fnmatch(f,'*.py'):
            fileSize= os.path.getsize( os.path.join(path,f) ) 
            print f, fileSize
            size += fileSize
print size

Длинноватый, но совершенно четкий и легко растяжимый.

С помощью zsh вы можете использовать расширенную глобализацию, чтобы:

du -c ** / *. отменить

find -name *.undo -print0 | du -hc --files0-from=-