Почему «find. -Name * .txt | xargs du -hc» дает несколько итогов? - PullRequest
8 голосов
/ 24 августа 2009

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

find . -name *.txt | xargs du -hc

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

Спасибо! Alex

Ответы [ 7 ]

12 голосов
/ 24 августа 2009

Как насчет использования опции --files0-from для du? Вы должны сгенерировать файл с нулевым символом в конце соответствующим образом:

find . -name "*txt" -exec echo -n -e {}"\0" \; | du -hc --files0-from=-

правильно работает в моей системе.

7 голосов
/ 21 октября 2010
find . -print0 -iname '*.txt' | du --files0-from=-

и если вы хотите иметь несколько различных расширений для поиска, лучше всего:

find . -type f -print0 | grep -azZEi '\.(te?xt|rtf|docx?|wps)$' | du --files0-from=-
5 голосов
/ 24 августа 2009

Программа xargs разбивает вещи на пакеты, чтобы учесть ограничения из-за максимальной длины командной строки unix. Это все еще более эффективно, чем запуск вашей подкоманды по одному, но для длинного списка входов она будет запускать команду достаточно раз, чтобы каждый «запуск» был достаточно коротким, чтобы не вызывать проблем.

Из-за этого вы, вероятно, видите одну выходную строку на «пакет», которую должен запустить xargs.

Поскольку вы можете найти это полезным / интересным, справочную страницу можно найти здесь: http://unixhelp.ed.ac.uk/CGI/man-cgi?xargs


Еще одна вещь, на которую следует обратить внимание (и это может быть опечатка в вашем посте или мое недоразумение), это то, что у вас есть "* .txt" неэкранированный / цитируемый. То есть у вас есть

find . -name *.txt | xargs du -hc

где вы, вероятно, хотите

find . -name \*.txt | xargs du -hc

Разница в том, что командная строка может расширять * в список имен файлов, которые совпадают ... вместо передачи * в find, который будет использовать его в качестве шаблона.

3 голосов
/ 23 августа 2012

Еще одно простое решение:

find . -name *.txt -print0 | xargs -0 du -hc
1 голос
/ 30 марта 2015

Одним из альтернативных решений является использование цикла bash for:

for i in `find . -name '*.txt'`; do du -hc $i | grep -v 'total'; done

Это хорошо, когда вам нужно больше контроля над тем, что происходит в цикле.

0 голосов
/ 24 августа 2009

Одним из альтернативных решений является использование awk:

find . -name "*.txt" -exec ls -lt {} \; | awk -F " " 'BEGIN { sum=0 } { sum+=$5 } END { print sum }'
0 голосов
/ 24 августа 2009

xargs вводит свои данные в куски разумного размера - то, что вы видите, является итогом для каждого из этих кусков. Проверьте man-страницу для xargs о том, как настроить обработку ввода.

...