bash - recursivamente - contar lineas linux grep
¿Cómo contar recursivamente todas las líneas de código en un directorio? (30)
WC -L? mejor uso GREP -C ^
wc -l? ¡Incorrecto! ¡El comando wc cuenta los nuevos códigos de líneas, no las líneas! Cuando la última línea del archivo no termina con el nuevo código de línea, ¡ esto no se 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, ten cuidado con la trampa wc -l (cuenta entre, no líneas !!!)
Tenemos una aplicación PHP y queremos contar todas las líneas de código en un directorio específico y sus subdirectorios. No necesitamos ignorar los comentarios, ya que solo estamos tratando de obtener una idea aproximada.
wc -l *.php
Ese comando funciona muy bien dentro de un directorio dado, pero ignora los subdirectorios. Estaba pensando que esto podría funcionar, pero está regresando a 74, lo que definitivamente no es el caso ...
find . -name ''*.php'' | wc -l
¿Cuál es la sintaxis correcta para alimentar todos los archivos?
Al menos en OS X, los comandos find + xarg + wc enumerados en algunas de las otras respuestas imprimen "total" varias veces en listas grandes, y no hay un total completo dado. Pude obtener un solo total para los archivos .c con el siguiente comando:
find . -name ''*.c'' -print0 |xargs -0 wc -l|grep -v total|awk ''{ sum += $1; } END { print "SUM: " sum; }''
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 en una de sus subcarpetas, o bien, wc
detiene
Distribuir primero los archivos más largos (es decir, ¿quizás estos archivos largos necesitan un poco de amor refactorizador?), Y excluir algunos directorios de proveedores:
find . -name ''*.php'' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less
En sistemas similares a UNIX, existe una herramienta llamada cloc
que proporciona estadísticas de código.
Me encontré con un directorio aleatorio en nuestro código base 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
-------------------------------------------------------------------------------
Excluyendo línea en blanco
find . -name "*.php" | xargs grep -v -c ''^$'' | awk ''BEGIN {FS=":"} { $cnt = $cnt + $2} END {print $cnt}''
Incluyendo líneas en blanco:
find . -name "*.php" | xargs wc -l
Hay una pequeña herramienta llamada sloccount para contar las líneas de código en el directorio. Debe tenerse en cuenta que hace más de lo que desea, ya que ignora las líneas / comentarios vacíos, agrupa los resultados por lenguaje de programación y calcula algunas estadísticas.
Lo que quieres es un simple for
bucle:
total_count=0
for file in $(find . -name *.php -print)
do
count=$(wc -l $file)
let total_count+=count
done
echo "$total_count"
Más común y simple para mí, suponga que necesita contar archivos de diferentes extensiones de nombre (por ejemplo, también nativos)
wc `find . -name ''*.[h|c|cpp|php|cc]''`
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
No necesitas todos estos comandos complicados y difíciles de recordar. Solo necesitas una herramienta llamada line-counter .
Un resumen rápido
Así es como se obtiene la herramienta.
$ pip install line-counter
Utilice el comando de line
para obtener el recuento de archivos y el recuento de líneas en el directorio actual (recursivamente)
$ line
Search in /Users/Morgan/Documents/Example/
file count: 4
line count: 839
Si quieres más detalles, solo usa la line -d
.
$ line -d
Search in /Users/Morgan/Documents/Example/
Dir A/file C.c 72
Dir A/file D.py 268
file A.py 467
file B.c 32
file count: 4
line count: 839
Y la mejor parte de esta herramienta es que puede agregar .gitignore
como configurar el archivo. Puedes configurar reglas para seleccionar o ignorar qué tipo de archivos contar como lo que haces en ''.gitignore''.
Más descripción y uso está aquí: https://github.com/MorganZhang100/line-counter
Otra variación :)
$ find -name ''*.php'' | xargs cat | wc -l
Editar: esto dará la suma total, en lugar de archivo por archivo.
Para Windows , la herramienta fácil y rápida es LocMetrics .
Para otro de una sola línea:
( find ./ -name ''*.php'' -print0 | xargs -0 cat ) | wc -l
trabaja en nombres con espacios, solo da salida a un número.
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 comentarios, etc. CLOC está disponible en Linux, Mac y Windows.
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
-------------------------------------------------------------------------------
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 usted quiere y además 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 lo complejo que es un proyecto antes de comenzar a trabajar con él.
Si desea que sea sencillo, elimine al intermediario y simplemente llame a wc
con todos los nombres de archivo:
wc -l `find . -name "*.php"`
O en la sintaxis moderna:
wc -l $(find . -name "*.php")
Funciona siempre que no haya espacios en ninguno de los nombres de directorio o nombres de directorio. Y siempre y cuando no tengas decenas de miles de archivos (los shells modernos admiten líneas de comando realmente largas). Su proyecto tiene 74 archivos, por lo que tiene mucho espacio para crecer.
Si desea que sus resultados se clasifiquen por número de líneas, puede simplemente 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
Si estás en Linux (y supongo que sí), recomiendo mi herramienta polyglot . Es dramáticamente más rápido que sloccount
o sloccount
y tiene más características que sloccount
.
Puedes invocarlo con
poly .
o
poly
así que es mucho más fácil de usar que algunos scripts bash complicados.
Si solo necesita el número total de líneas, digamos sus archivos PHP, puede usar un comando de una línea muy simple incluso en Windows si tiene instalado GnuWin32. Me gusta esto:
cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l
Debe especificar dónde está exactamente el find.exe; de lo contrario, se ejecutará el FIND.EXE provisto por Windows (de los antiguos comandos similares a DOS), ya que probablemente se encuentre antes de GnuWin32 en el entorno PATH, y tiene diferentes parámetros y resultados.
Tenga en cuenta que en el comando anterior debe usar comillas inversas, no comillas simples.
Si usas una versión bastante 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 el **
glob-operator no es recursivo. Para habilitar esta configuración, emita
shopt -s globstar
Para hacer esto permanente, agréguelo a uno de los archivos de inicialización ( ~/.bashrc
, ~/.bash_profile
etc.).
Sorprendentemente, no hay respuesta basada en -exec
- -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 encontrar por extensión de archivo, use -name
:
find . -name *.py -exec wc -l {} /; | awk ''{ SUM += $0} END { print SUM }''
Suponiendo que nadie verá esto enterrado en la parte posterior ... Sin embargo, hasta ahora ninguna de las respuestas aborda el problema de los nombres de archivo con espacios. Además, todo lo que use xargs
está sujeto a fallar si la longitud total de las rutas en el árbol excede el límite de tamaño del entorno de shell (el valor predeterminado es de unos pocos megabytes en Linux). Aquí hay uno que soluciona estos problemas de una manera bastante directa. La subshell se encarga de los archivos con espacios. El awk
totaliza el flujo de salidas individuales de archivos wc
, por lo que nunca debe quedarse sin espacio. También restringe el exec
a archivos solamente (saltando directorios):
find . -type f -name ''*.php'' -exec bash -c ''wc -l "$0"'' {} /; | awk ''{s+=$1} END {print s}''
También puedes probar cloc.sourceforge.net (requiere Perl)
Una sencilla que será rápida, usará todo el poder de búsqueda / filtrado de la find
, no fallará cuando haya demasiados archivos (desbordamiento de argumentos numéricos), funcionará bien con archivos con símbolos divertidos en su nombre, sin usar xargs
, no funcionará ejecute una cantidad inútil de comandos externos (gracias a +
para find
''s -exec
). Aqui tienes:
find . -name ''*.php'' -type f -exec cat -- {} + | wc -l
Usé este script en línea que lanzo 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.
aunque me gustan los scripts, prefiero este, ya que también muestra un resumen por archivo, siempre y cuando el total
wc -l `find . -name "*.php"`
sólo para fuentes:
wc `find`
para filtrar, solo usa grep
wc `find | grep .php$`
POSIX
A diferencia de la mayoría de las otras respuestas aquí, estas funcionan en cualquier sistema POSIX, para cualquier número de archivos y con cualquier nombre de archivo (excepto donde se indique).
Líneas en cada archivo:
find . -name ''*.php'' -type f -exec wc -l {} /;
# faster, but includes total at end if there are multiple files
find . -name ''*.php'' -type f -exec wc -l {} +
Líneas en cada archivo, ordenadas por ruta de archivo
find . -name ''*.php'' -type f | sort | xargs -L1 wc -l
# for files with spaces or newlines, use the non-standard sort -z
find . -name ''*.php'' -type f -print0 | sort -z | xargs -0 -L1 wc -l
Líneas en cada archivo, ordenadas por número de líneas, descendiendo
find . -name ''*.php'' -type f -exec wc -l {} /; | sort -nr
# faster, but includes total at end if there are multiple files
find . -name ''*.php'' -type f -exec wc -l {} + | sort -nr
Total de líneas en todos los archivos.
find . -name ''*.php'' -type f -exec cat {} + | wc -l
Tratar:
find . -name ''*.php'' | xargs wc -l
La herramienta SLOCCount puede ayudar también.
Proporcionará una fuente precisa de líneas de código para la jerarquía a la que apunte, así como algunas estadísticas adicionales.