Используйте find, wc и sed для подсчета строк - PullRequest
24 голосов
/ 11 сентября 2009

Я пытался использовать sed для подсчета всех строк на основе определенного расширения.

find -name '*.m' -exec wc -l {} \; | sed ...

Я пытался сделать следующее, как бы я включил sed в эту конкретную строку, чтобы получить итоги.

Ответы [ 8 ]

46 голосов
/ 11 сентября 2009

Вы также можете получить хорошее форматирование с помощью wc:

wc `find -name '*.m'`
13 голосов
/ 07 января 2012

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

find . -type f -name "*.m" -print0 | xargs -0 cat | wc -l

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

6 голосов
/ 11 сентября 2009

Вы можете cat всех файлов через один wc экземпляр, чтобы получить общее количество строк:

find . -name '*.m' -exec cat {} \; | wc -l
5 голосов
/ 05 июня 2011

На современных платформах GNU wc и найдите параметры take -print0 и -files0-from, которые можно объединить в команду, которая считает строки в файлах с итоговым значением в конце. Пример:

find . -name '*.c' -type f -print0 | wc -l --files0-from=-
4 голосов
/ 11 сентября 2009

вы можете использовать sed также для подсчета строк вместо wc:

 find . -name '*.m' -exec sed -n '$=' {} \;

, где '$=' - это «специальная переменная», которая хранит количество строк

EDIT

Вы также можете попробовать что-то вроде sloccount

2 голосов
/ 11 сентября 2009

Хм, решение с cat может быть проблематичным, если у вас много файлов, особенно больших.

Второе решение не дает итогового значения, только строки на файл, как я тестировал.

Я предпочитаю что-то вроде этого:

find . -name '*.m' | xargs wc -l | tail -1

Это выполнит работу быстро, независимо от того, сколько у вас файлов и сколько у вас файлов.

1 голос
/ 14 сентября 2009

Для больших каталогов мы должны использовать:

find . -type f -name '*.m' -exec sed -n '$=' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}' 

# alternative using awk twice
find . -type f -name '*.m' -exec awk 'END {print NR}' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}' 
1 голос
/ 12 сентября 2009

sed не является подходящим инструментом для подсчета. Вместо этого используйте awk:

find . -name '*.m' -exec awk '{print NR}' {} +

Использование + вместо \; заставляет находить вызов awk через каждые N найденных файлов (как с xargs).

...