
Em um projeto com milhares de arquivos, eu queria comparar o total de linhas de código com linhas de código apenas em PHP (descartando CSS, JavaScript, etc.).
Quando eu corro
find . -type f | xargs wc -l
o total na última linha émais baixodo que quando eu corro
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l
Considerando que o segundo find
deve ser uma lista menor de arquivos do que (é um subconjunto estrito) do primeiro find
, como poderia wc
relatar um total maior no segundo caso?
Responder1
xargs
só pode passar ARG_MAXbytes de argumentos para wc
.
No meu Mac, ARG_MAX é menor que os nomes completos dos arquivos e os caminhos relativos dos arquivos de todo o projeto, portanto, noprimeirocomando, xargs
despejou os resultados do find
towc
em dois lotes, o que significava que wc
colocar para foradois totais, cercado por milhares de nomes de arquivos. Mas ARG_MAX era maior que osegundo find
saída, então o segundo achado menor é mostrado emum wc
total.
A solução foi usar estes comandos, para que eu pudesse ver todos os totais sem as (chatas) linhas de contagem de arquivos individuais:
find . -type f | xargs wc -l | grep total
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l | grep total
Em seguida, some as várias linhas do "total" manualmente.
Responder2
Há muitas maneiras de fazer isso e xargs
não é a melhor. Aqui estão alguns:
O mais simples é
cat
cada um dos arquivos encontradosfind
e contar as linhas. Cuidado, isso só funciona se os nomes dos seus arquivos não tiverem espaços ou caracteres estranhos: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
Se for provável que os nomes dos seus arquivos contenham caracteres estranhos (barras, espaços, etc.), use isto:
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
A melhor maneira é usar
-exec
a opção find:find . -name "*.pep" -exec cat {} \; | wc find -E . -regex '.+\.(php|inc)' -type f -exec cat {} \; | wc
Responder3
Use awk
para somar os vários números "totais" das wc -l
saídas!
(Nota: wc -l
retorna o número de caracteres de nova linha, ou seja, "linhas" finais sem um \n
caractere final não serão contadas - como é o caso de awk
ou 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}'