si quiero contar las líneas de código, lo trivial es
cat *.c *.h | wc -l
¿Pero qué pasa si tengo varios subdirectorios?
fuente
si quiero contar las líneas de código, lo trivial es
cat *.c *.h | wc -l
¿Pero qué pasa si tengo varios subdirectorios?
Probablemente debería usar SLOCCount o cloc para esto, están diseñados específicamente para contar líneas de código fuente en un proyecto, independientemente de la estructura del directorio, etc .; ya sea
sloccount .
o
cloc .
producirá un informe sobre todo el código fuente a partir del directorio actual.
Si quieres usar findy wc, GNU wctiene una buena --files0-fromopción:
find . -name '*.[ch]' -print0 | wc --files0-from=-
(¡Gracias a SnakeDoc por la sugerencia de cloc !)
sloccount /tmp/stackexchange(creada nuevamente el 17 de mayo después de mi reinicio más reciente) dice que el costo estimado para desarrollar los archivos sh, perl, awk, etc. que encontró es de $ 11,029. y eso no incluye las frases que nunca se convirtieron en un archivo de script.
Como el wccomando puede tomar múltiples argumentos, puede pasar todos los nombres de archivo para wcusar el +argumento de la -execacción de GNU find:
find . -type f -name '*.[ch]' -exec wc -l {} +
Alternativamente, en bash, usando la opción de shell globstarpara recorrer los directorios de forma recursiva:
shopt -s globstar
wc -l **/*.[ch]
Otros shells atraviesan recursivamente por defecto (p zsh. Ej. ) O tienen opciones similares como globstar, bueno, al menos la mayoría.
Puede usar findjunto con xargsy wc:
find . -type f -name '*.h' -o -name '*.c' | xargs wc -l
totallíneas si wcse invocan varios s).
wcproblema de varios comandos puede abordarse canalizando finda la while read FILENAME; do . . .doneestructura. Y dentro del uso del bucle while wc -l. El resto es resumir las líneas totales en una variable y mostrarla.
Si se encuentra en un entorno donde no tiene acceso, clocetc., le sugiero
find -name '*.[ch]' -type f -exec cat '{}' + | grep -c '[^[:space:]]'
Recorrido: findbusca de forma recursiva todos los archivos normales cuyo nombre termina en o .co .hy se ejecuta caten ellos. La salida se canaliza greppara contar todas las líneas que no están en blanco (las que contienen al menos un carácter sin espaciado).
Como se ha señalado en los comentarios, nocat file | wc -l es equivalente a porque el primero imprime solo un número mientras que el segundo imprime un número y el nombre del archivo. Del mismo modo , imprimirá solo un número, mientras que imprimirá una línea de información para cada archivo.wc -l filecat * | wc -lwc -l *
En un espíritu de simplicidad, volvamos a la pregunta que realmente se hizo:
si quiero contar las líneas de código, lo trivial es
cat *.c *.h | wc -l¿Pero qué pasa si tengo varios subdirectorios?
En primer lugar, puede simplificar incluso su comando trivial para:
cat *.[ch] | wc -l
Y finalmente, el equivalente de muchos subdirectorios es:
find . -name '*.[ch]' -exec cat {} + | wc -l
Quizás esto podría mejorarse de muchas maneras, como restringir los archivos coincidentes solo a archivos normales (no directorios) agregando, -type fpero el findcomando dado es el equivalente recursivo exacto de cat *.[ch].
Muestra usando awk:
find . -name '*.[ch]' -exec wc -l {} \; |
awk '{SUM+=$1}; END { print "Total number of lines: " SUM }'
+en lugar de \;.
wc -lpara grupos de archivos, más o menos como lo xargshace, pero maneja caracteres extraños (como espacios) en los nombres de los archivos sin necesidad de ninguno de xargslos dos (no estándar) -print0y -0opciones findy xargsrespectivamente. Es una optimización menor. La desventaja sería que cada invocación de wcgeneraría un recuento total de líneas al final cuando se le otorgan múltiples archivos; el awkscript se ocuparía de eso. Por lo tanto, no es un slam-dunk, pero muy a menudo, usar +en lugar de \;con findes una buena idea.
wc. Si se desconoce a priori el número de archivos que se encontrarán , ¿existe el riesgo de pasar ese límite o de alguna manera se maneja mediante find?
findagrupa los archivos en paquetes de tamaño conveniente, que no excederá el límite de longitud para la lista de argumentos en la plataforma, permitiendo el entorno (que sale de la longitud de la lista de argumentos, por lo que la longitud de la lista de argumentos más el La longitud del entorno debe ser inferior a un valor máximo). IOW, findhace bien el trabajo, como xargshace bien el trabajo.
comando fácil:
find . -name '*.[ch]' | xargs wc -l
totallíneas si wcse invocan varios s).
find . -name \*.[ch] -print | xargs -n 1 wc -ldebería hacer el truco. También hay varias variaciones posibles sobre eso, como usar en -execlugar de canalizar la salida a wc.
find . -name \*.[ch] -printno imprime el contenido de los archivos, solo los nombres de los archivos. Entonces, cuento la cantidad de archivos, ¿no? ¿Necesito 'xargs'?
xargs, y también necesitaría estar atento a las wcinvocaciones múltiples si tiene muchos archivos; deberías buscar todas las totallíneas y sumarlas.
find . -name \*.[ch] -print0 | xargs -0 cat | wc -l
find . -name \*.[ch] -print | wc -l) cuenta el número de archivos (a menos que el nombre de un archivo contenga una nueva línea, pero eso es muy inusual), no cuenta el número de líneas en los archivos.
cat?wc -l *.c *.hhace lo mismowc -l *.c *.h | tail -n 1obtener una salida similar.**, por lo que podría haber utilizadowc -l **/*.{h,c}o algo similar. Tenga en cuenta que en Bash, al menos, esta opción (llamadaglobstar) está desactivada de forma predeterminada. Pero también tenga en cuenta que en este caso particular,clocoSLOCCountes una opción mucho mejor. (Además,ackpuede ser preferiblefindpara encontrar / enumerar fácilmente archivos fuente.)