Почему утилита туалета генерирует несколько строк с “общим количеством”?

Я использую утилиту туалета в сценарии оболочки, который я выполняю из Cygwin, и я заметил, что существует больше чем одна строка с "общим количеством" в ее выводе.

Следующая функция используется для подсчета количества строк в моих исходных файлах:

count_curdir_src() {
    find . '(' -name '*.vb' -o -name '*.cs' ')' \
        -a '!' -iname '*.Designer.*' -a '!' -iname '.svn' -print0 | \
    xargs -0 wc -l
}

Но его вывод для определенного каталога похож на это:

$ find . '(' -name '*.vb' -o -name '*.cs' ')' -a '!' -iname '*.Designer.*' -a '!' -iname '.svn' -print0 | xargs -0 wc -l
     19 ./dirA/fileABC.cs
    640 ./dirA/subdir1/fileDEF.cs
    507 ./dirA/subdir1/fileGHI.cs
   2596 ./dirA/subdir1/fileJKL.cs
(...many others...)
     58 ./dirB/fileMNO.cs
     36 ./dirB/subdir1/filePQR.cs
 122200 total
  6022 ./dirB/subdir2/subsubdir/fileSTU.cs
    24 ./dirC/fileVWX.cs
(...)
    36 ./dirZ/Properties/AssemblyInfo.cs
    88 ./dirZ/fileYZ.cs
 25236 total

Это похоже на сброс туалета где-нибудь в процессе. Это не может быть вызвано пробелами в именах файлов или именах каталогов, потому что я использую -print0 опция. И это только происходит, когда я выполняю его на своем дереве крупнейшего источника.

Так, действительно ли это - ошибка в туалете, или в Cygwin? Или что-то еще? В странице справочника туалета говорится:

Распечатайте новую строку, слово и счета байта для каждого ФАЙЛА и общей строки, если больше чем один ФАЙЛ указан.

Это ничего не упоминает о нескольких общих строках (промежуточное общее количество рассчитывает или что-то), поэтому кто виноват здесь?

6
задан HyperQuantum 23 March 2010 в 15:53
поделиться

2 ответа

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

Один из альтернативных вариантов - использовать временный файл и параметр - files0-from для wc :

$ find . '(' -name '*.vb' -o -name '*.cs' ')' -a '!' -iname '*.Designer.*' -a 
    '!' -iname   '.svn' -print0 > files

$ wc --files0-from files
3
ответ дан 10 December 2019 в 00:36
поделиться

Что происходит, так это то, что xargs запускает wc несколько раз. xargs по умолчанию объединяет столько аргументов, сколько считает возможным, при каждом вызове команды, которую он должен запустить, но если файлов слишком много, он будет запускать команду несколько раз для подмножеств файлов.

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

wc -l $(find . '(' -name '*.vb' -o -name '*.cs' ')' \
    -a '!' -iname '*.Designer.*' -a '!' -iname '.svn' )

и вы также потеряете возможности print0.

Другой - использовать сценарий awk (или perl ) для обработки вывода вашей комбинации find / xargs , пропустите «итоговые» строки и просуммируйте итоги самостоятельно.

5
ответ дан 10 December 2019 в 00:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: