
В проекте с тысячами файлов мне захотелось сравнить общее количество строк кода со строками кода только на PHP (без учета CSS, JavaScript и т. д.).
Когда я бегу
find . -type f | xargs wc -l
итог в последней строке равеннижечем когда я бегу
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l
Учитывая, что второй find
список файлов должен быть меньше первого (является его строгим подмножеством) find
, как можно было бы wc
сообщить о большем общем количестве во втором случае?
решение1
xargs
может только пройти ARG_MAXбайты аргументов в wc
.
На моем Mac ARG_MAX меньше, чем полные имена файлов и относительные пути всех файлов проекта, поэтому впервыйкоманда, сбросила xargs
результатыfind
wc
в двух партиях, что означало, что wc
потушитьдва итога, окруженный тысячами имен файлов. Но ARG_MAX оказался больше, чемвторой find
выход, поэтому второй, меньший результат поиска показал всеодин wc
общий.
Исправление заключалось в использовании этих команд, чтобы я мог видеть все итоговые данные без (скучных) строк с количеством отдельных файлов:
find . -type f | xargs wc -l | grep total
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l | grep total
Затем вручную просуммируйте несколько строк «итого».
решение2
Есть много способов сделать это, и xargs
это не лучший из них. Вот несколько:
Самый простой, это для
cat
каждого из найденных файловfind
и подсчет строк. Осторожно, это работает только если имена ваших файлов не содержат пробелов или странных символов:find . -type f | while read n; do cat $n; done | wc -l find -E . -regex '.+\.(php|inc)' -type f | while read n; do cat $n; done | wc -l
Если имена ваших файлов, скорее всего, содержат странные символы (слеши, пробелы и т. д.), используйте это:
find . -type f | while IFS= read -r n; do cat $n; done | wc -l find -E . -regex '.+\.(php|inc)' -type f | while IFS= read -r n; do cat $n; done | wc -l
Лучший способ — использовать
-exec
опцию find:find . -name "*.pep" -exec cat {} \; | wc find -E . -regex '.+\.(php|inc)' -type f -exec cat {} \; | wc
решение3
Используйте awk
для суммирования различных «общих» чисел выходов wc -l
!
(Примечание: wc -l
возвращает количество символов новой строки, т.е. конечные «строки» без конечного \n
символа не будут учитываться — как в случае с awk
или sed
.)
export LC_ALL=C
find . -type f -print0 | xargs -0 wc -l |
awk '/^ *[[:digit:]]+ total$/{ total+=$1 }END{print total}'
# xargs alternatives using: find ... -exec <wc|awk|sed> ... '{}' +
#man find | less -p '{} \+'
# wc
find . -type f -exec wc -l '{}' + 2>/dev/null |
awk '/^ *[[:digit:]]+ total$/{ total+=$1 }END{print total}'
# awk
find . -type f -exec awk 'END {print NR}' '{}' + 2>/dev/null |
awk '{ total+=$1 }END{print total}'
# sed
find . -type f -exec sed -n '$=' '{}' + 2>/dev/null |
awk '{ total+=$1 }END{print total}'