
En un proyecto con miles de archivos, quería comparar el total de líneas de código con líneas de código solo en PHP (descartando CSS, JavaScript, etc.).
cuando corro
find . -type f | xargs wc -l
el total en la última línea esmás bajoque cuando corro
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l
Teniendo en cuenta que el segundo find
tiene que ser una lista de archivos más pequeña que (es un subconjunto estricto de) el primero find
, ¿cómo podría wc
informar un total más alto en el segundo caso?
Respuesta1
xargs
sólo puede pasar ARG_MAXbytes de argumentos para wc
.
En mi Mac, ARG_MAX es más pequeño que los nombres completos de los archivos y las rutas relativas de todos los archivos del proyecto, por lo que en elprimerocomando, xargs
arrojó los resultados del find
awc
en dos lotes, lo que significaba que wc
se apagódos totales, rodeado de miles de nombres de archivos. Pero resultó que ARG_MAX era más grande que elsegundo find
salida, por lo que el segundo hallazgo más pequeño se muestra enuno wc
total.
La solución fue usar estos comandos, para poder ver todos los totales sin las (aburridas) líneas de recuento de archivos individuales:
find . -type f | xargs wc -l | grep total
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l | grep total
Luego sume las varias filas "totales" a mano.
Respuesta2
Hay muchas maneras de hacer esto y xargs
no es la mejor. Aquí hay un par:
La más sencilla, es pasar por
cat
cada uno de los archivos encontradosfind
y contar las líneas. Cuidado, esto solo funciona si los nombres de tus archivos no tienen espacios ni caracteres extraños: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
Si es probable que los nombres de sus archivos contengan caracteres extraños (barras, espacios, etc.), utilice esto en su lugar:
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
Una mejor manera es usar
-exec
la opción de buscar:find . -name "*.pep" -exec cat {} \; | wc find -E . -regex '.+\.(php|inc)' -type f -exec cat {} \; | wc
Respuesta3
¡Úselo awk
para resumir los diversos números "totales" de las wc -l
salidas!
(Nota: wc -l
devuelve el número de caracteres de nueva línea, es decir, las "líneas" finales sin un \n
carácter final no se contarán, como es el caso de awk
o 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}'