¿Cómo contar todas las líneas de código en un directorio recursivamente?

Tenemos una aplicación PHP y queremos contar todas las líneas de código bajo un directorio específico y sus subdirectorios. No necesitamos ignorar los comentarios, ya que solo estamos tratando de tener una idea aproximada.

wc -l *.php 

Ese comando funciona muy bien dentro de un directorio determinado, pero ignora los subdirectorios. Estaba pensando que esto podría funcionar, pero está devolviendo 74, que definitivamente no es el caso …

 find . -name '*.php' | wc -l 

¿Cuál es la syntax correcta para alimentar en todos los archivos?

Tratar:

 find . -name '*.php' | xargs wc -l 

La herramienta SLOCCount también puede ser útil.

Proporcionará una fuente precisa de conteo de código para la jerarquía a la que lo diriges, así como algunas estadísticas adicionales.

Para otro one-liner:

 ( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l 

trabaja con nombres con espacios, solo emite un número.

Si utiliza una versión decentemente reciente de Bash (o ZSH), es mucho más simple:

 wc -l **/*.php 

En el shell Bash esto requiere que se globstar opción globstar ; de lo contrario, ** glob-operator no es recursivo. Para habilitar esta configuración, emita

 shopt -s globstar 

Para que esto sea permanente, agréguelo a uno de los archivos de inicialización ( ~/.bashrc , ~/.bash_profile etc.).

Puede usar la utilidad cloc que está construida para este propósito exacto. Informa cada una de la cantidad de líneas en cada idioma, junto con la cantidad de líneas que son comentarios, etc.

Ejemplo de uso y salida:

 $ cloc --exclude-lang=DTD,Lua,make,Python . 2570 text files. 2200 unique files. 8654 files ignored. http://cloc.sourceforge.net v 1.53 T=8.0 s (202.4 files/s, 99198.6 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Javascript 1506 77848 212000 366495 CSS 56 9671 20147 87695 HTML 51 1409 151 7480 XML 6 3088 1383 6222 ------------------------------------------------------------------------------- SUM: 1619 92016 233681 467892 ------------------------------------------------------------------------------- 

En los sistemas tipo UNIX, hay una herramienta llamada cloc que proporciona estadísticas de código.

Ejecuté un directorio aleatorio en nuestra base de código que dice:

  59 text files. 56 unique files. 5 files ignored. http://cloc.sourceforge.net v 1.53 T=0.5 s (108.0 files/s, 50180.0 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- C 36 3060 1431 16359 C/C++ Header 16 689 393 3032 make 1 17 9 54 Teamcenter def 1 10 0 36 ------------------------------------------------------------------------------- SUM: 54 3776 1833 19481 ------------------------------------------------------------------------------- 

No especificó cuántos archivos hay o cuál es el resultado deseado. Es esto lo que estás buscando:

 find . -name '*.php' | xargs wc -l 

Sin embargo, otra variación 🙂

 $ find -name '*.php' | xargs cat | wc -l 

Editar: esto dará la sum total, en lugar de archivo por archivo.

Hay una pequeña herramienta llamada sloccount para contar las líneas de código en el directorio. Cabe señalar que hace más de lo que desea, ya que ignora las líneas vacías / comentarios, agrupa los resultados por lenguaje de progtwigción y calcula algunas estadísticas.

Más común y simple en cuanto a mí, supongamos que necesita contar archivos de diferentes extensiones de nombre (por ejemplo, también nativos)

 wc `find . -name '*.[h|c|cpp|php|cc]'` 

POSIX

Líneas en cada archivo:

 find . -name '*.php' -type f | xargs wc -l 

Líneas en cada archivo, ordenadas por ruta de archivo

 find . -name '*.php' -type f | sort | xargs wc -l 

Líneas en cada archivo, ordenadas por número de líneas, descendiendo

 find . -name '*.php' -type f | xargs wc -l | sort -nr 

Total de líneas en todos los archivos

 find . -name '*.php' -type f | xargs cat | wc -l 

Sorprendentemente, no hay respuesta basada en find’s -exec y awk . Aquí vamos:

 find . -type f -exec wc -l {} \; | awk '{ SUM += $0} END { print SUM }' 

Este fragmento encuentra para todos los archivos ( -type f ). Para buscar por extensión de archivo, use -name :

 find . -name *.py -exec wc -l {} \; | awk '{ SUM += $0} END { print SUM }' 

Una sencilla que sea rápida, utilizará todo el poder de búsqueda / filtrado de find , no fallará cuando haya demasiados archivos (número de argumentos overflow), funcione bien con archivos con símbolos divertidos en su nombre, sin usar xargs , no lo hará lanzar una cantidad inútilmente alta de comandos externos (gracias a + para find ‘s -exec ). Aqui tienes:

 find . -name '*.php' -type f -exec cat -- {} + | wc -l 

solo para fonts:

 wc `find` 

para filtrar, solo use grep

 wc `find | grep .php$` 

lo que quieres es un bucle simple para:

 total_count=0 for file in $(find . -name *.php -print) do count=$(wc -l $file) let total_count+=count done echo $total_count 

También puedes probar CLOC (requiere Perl)

Supongo que nadie verá esto enterrado en la parte posterior … Sin embargo, ninguna de las respuestas hasta ahora aborda el problema de los nombres de archivos con espacios. Además, todos los que usan xargs pueden fallar si la longitud total de las rutas en el árbol excede el límite de tamaño del entorno de la shell (el valor predeterminado es unos pocos megabytes en Linux). Aquí hay uno que soluciona estos problemas de una manera bastante directa. La subshell se ocupa de los archivos con espacios. El awk sum el flujo de salidas individuales de archivos de archivos, por lo que nunca debería quedarse sin espacio. También restringe el exec a archivos solamente (omitiendo directorios):

 find . -type f -name '*.php' -exec bash -c 'wc -l "$0"' {} \; | awk '{s+=$1} END {print s}' 

Sé que la pregunta está etiquetada como bash , pero parece que el problema que estás tratando de resolver también está relacionado con PHP.

Sebastian Bergmann escribió una herramienta llamada PHPLOC que hace lo que quiere y, además de eso, le proporciona una visión general de la complejidad de un proyecto. Este es un ejemplo de su informe:

 Size Lines of Code (LOC) 29047 Comment Lines of Code (CLOC) 14022 (48.27%) Non-Comment Lines of Code (NCLOC) 15025 (51.73%) Logical Lines of Code (LLOC) 3484 (11.99%) Classes 3314 (95.12%) Average Class Length 29 Average Method Length 4 Functions 153 (4.39%) Average Function Length 1 Not in classes or functions 17 (0.49%) Complexity Cyclomatic Complexity / LLOC 0.51 Cyclomatic Complexity / Number of Methods 3.37 

Como puede ver, la información proporcionada es mucho más útil desde la perspectiva de un desarrollador, ya que puede decirle aproximadamente qué tan complejo es un proyecto antes de comenzar a trabajar con él.

WC -L? mejor uso GREP -C ^

wc -l? ¡Incorrecto! El comando wc cuenta códigos de líneas nuevas, ¡ no líneas! Cuando la última línea del archivo no finaliza con un nuevo código de línea, ¡ esto no contará!

si aún desea contar líneas, use grep -c ^ , ejemplo completo:

 #this example prints line count for all found files total=0 find /path -type f -name "*.php" | while read FILE; do #you see use grep instead wc ! for properly counting count=$(grep -c ^ < "$FILE") echo "$FILE has $count lines" let total=total+count #in bash, you can convert this for another shell done echo TOTAL LINES COUNTED: $total 

finalmente, cuidado con la trampa wc-l (¡¡¡los conteos entran, no las líneas !!!)

Si desea que sus resultados se clasifiquen por el número de líneas, solo puede agregar | sort | sort o | sort -r | sort -r ( -r para orden descendente) a la primera respuesta, así:

 find . -name '*.php' | xargs wc -l | sort -r 

Algo diferente:

 wc -l `tree -if --noreport | grep -e'\.php$'` 

Esto funciona bien, pero necesita tener al menos un archivo *.php en la carpeta actual o una de sus subcarpetas, o si no, wc stalls

Si necesita solo el número total de líneas en sus archivos PHP, puede usar un comando muy simple de una línea incluso en Windows si tiene instalado GnuWin32. Me gusta esto:

 cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l 

Deberá especificar dónde exactamente se encuentra el find.exe; de ​​lo contrario, se ejecutará el FIND.EXE proporcionado por Windows (de los antiguos comandos tipo DOS), ya que probablemente esté antes del GnuWin32 en el entorno PATH, y tenga diferentes parámetros y resultados.

Tenga en cuenta que en el comando de arriba debe usar comillas, no comillas simples.

Repartir primero los archivos más largos (es decir, ¿quizás estos archivos largos necesitan un poco de refactorización?) Y excluir algunos directorios de proveedores:

  find . -name '*.php' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less 

Para Windows , la herramienta fácil y rápida es LocMetrics .

En OS X al menos, los comandos find + xarg + wc enumerados en algunas de las otras respuestas imprimen “total” varias veces en listados grandes, y no se proporciona un total completo. Pude obtener un total único para archivos .c con el siguiente comando:

find . -name '*.c' -print0 |xargs -0 wc -l|grep -v total|awk '{ sum += $1; } END { print "SUM: " sum; }'

mientras que me gustan los guiones, prefiero este, ya que también muestra un resumen por archivo, siempre y cuando un total

 wc -l `find . -name "*.php"` 

Si quiere mantenerlo simple, recorte el intermediario y simplemente llame a wc con todos los nombres de archivo:

 wc -l `find . -name "*.php"` 

O en la syntax moderna:

 wc -l $(find . -name "*.php") 

Funciona siempre que no haya espacios en ninguno de los nombres de directorio o archivos. Y siempre que no tenga decenas de miles de archivos (las conchas modernas admiten líneas de comando realmente largas). Su proyecto tiene 74 archivos, por lo que tiene mucho espacio para crecer.

muy simple

 find /path -type f -name "*.php" | while read FILE do count=$(wc -l < $FILE) echo "$FILE has $count lines" done 
 $cd directory $wc -l* | sort -nr 

Tengo la caja ocupada instalada en mi sistema de Windows. Entonces esto es lo que hice.

 ECHO OFF for /r %%G in (*.php) do ( busybox grep . "%%G" | busybox wc -l ) 

Usé este script en línea que lancé desde el directorio de src-project:

  for i in $(find . -type f); do rowline=$(wc -l $i | cut -f1 -d" "); file=$(wc -l $i | cut -f2 -d" "); lines=$((lines + rowline)); echo "Lines["$lines"] " $file "has "$rowline"rows."; done && unset lines 

Eso produce esta salida:

 Lines[75] ./Db.h has 75rows. Lines[143] ./Db.cpp has 68rows. Lines[170] ./main.cpp has 27rows. Lines[294] ./Sqlite.cpp has 124rows. Lines[349] ./Sqlite.h has 55rows. Lines[445] ./Table.cpp has 96rows. Lines[480] ./DbError.cpp has 35rows. Lines[521] ./DbError.h has 41rows. Lines[627] ./QueryResult.cpp has 106rows. Lines[717] ./QueryResult.h has 90rows. Lines[828] ./Table.h has 111rows.