programa por para lineas extension directorios directorio conteo contar comando archivos linux bash unix wc

linux - por - programa para contar archivos



Cómo contar las líneas de código, incluidos los subdirectorios (11)

Esta pregunta ya tiene una respuesta aquí:

Supongamos que quiero contar las líneas de código en un proyecto. Si todos los archivos están en el mismo directorio que puedo ejecutar:

cat * | wc -l

Sin embargo, si hay subdirectorios, esto no funciona. Para que esto funcione, el gato debería tener un modo recursivo. Sospecho que este podría ser un trabajo para xargs, pero me pregunto si hay una solución más elegante.


Aquí hay un script Bash que cuenta las líneas de código en un proyecto. Atraviesa un árbol fuente recursivamente y excluye las líneas en blanco y los comentarios de una sola línea que usan "//".

# $excluded is a regex for paths to exclude from line counting excluded="spec/|node_modules/|README/|lib/|docs/|csv/|XLS/|json/|png" countLines(){ # $total is the total lines of code counted total=0 # -mindepth exclues the current directory (".") for file in `find . -mindepth 1 -name "*.*" |grep -v "$excluded"`; do # First sed: only count lines of code that are not commented with // # Second sed: don''t count blank lines # $numLines is the lines of code numLines=`cat $file | sed ''//////d'' | sed ''/^/s*$/d'' | wc -l` total=$(($total + $numLines)) echo " " $numLines $file done echo " " $total in total } echo Source code files: countLines echo Unit tests: cd spec countLines

Aquí se muestra el resultado de mi proyecto :

Source code files: 2 ./buildDocs.sh 24 ./countLines.sh 15 ./css/dashboard.css 53 ./data/un_population/provenance/preprocess.js 19 ./index.html 5 ./server/server.js 2 ./server/startServer.sh 24 ./SpecRunner.html 34 ./src/computeLayout.js 60 ./src/configDiff.js 18 ./src/dashboardMirror.js 37 ./src/dashboardScaffold.js 14 ./src/data.js 68 ./src/dummyVis.js 27 ./src/layout.js 28 ./src/links.js 5 ./src/main.js 52 ./src/processActions.js 86 ./src/timeline.js 73 ./src/udc.js 18 ./src/wire.js 664 in total Unit tests: 230 ./ComputeLayoutSpec.js 134 ./ConfigDiffSpec.js 134 ./ProcessActionsSpec.js 84 ./UDCSpec.js 149 ./WireSpec.js 731 in total

¡Disfrutar! - Curran


Creo que probablemente estés atrapado con xargs

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

El método de chromakode da el mismo resultado pero es mucho más lento. Si usas xargs, tu cat y wc ing pueden comenzar tan pronto como encuentres comiencen a encontrar.

Buena explicación en Linux: xargs vs. exec {}


Intenta usar el comando find , que recursifica los directorios por defecto:

find . -type f -execdir cat {} /; | wc -l


La forma correcta es:

find . -name "*.c" -print0 | xargs -0 cat | wc -l

Debe usar -print0 porque solo hay dos caracteres no válidos en los nombres de archivo Unix: el byte nulo y "/" (barra inclinada). Entonces, por ejemplo, "xxx / npasswd" es un nombre válido. En realidad, es más probable que encuentres nombres con espacios en ellos. Los comandos anteriores contarían cada palabra como un archivo separado.

También puede usar "-type f" en lugar de -name para limitar la búsqueda a los archivos.


Me gusta usar find y head together para "un gato recursivo" en todos los archivos en un directorio de proyecto, por ejemplo:

find . -name "*rb" -print0 | xargs -0 head -10000

La ventaja es que head agregará su nombre de archivo y ruta de acceso:

==> ./recipes/default.rb <== DOWNLOAD_DIR = ''/tmp/downloads'' MYSQL_DOWNLOAD_URL = ''http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.10-debian6.0-x86_64.deb'' MYSQL_DOWNLOAD_FILE = "#{DOWNLOAD_DIR}/mysql-5.6.10-debian6.0-x86_64.deb" package "mysql-server-5.5" ... ==> ./templates/default/my.cnf.erb <== # # The MySQL database server configuration file. # ... ==> ./templates/default/mysql56.sh.erb <== PATH=/opt/mysql/server-5.6/bin:$PATH

Para ver el ejemplo completo aquí, consulte la publicación de mi blog:

http://haildata.net/2013/04/using-cat-recursively-with-nicely-formatted-output-including-headers/

Nota: usé ''head -10000'', claramente si tengo archivos de más de 10,000 líneas, esto va a truncar la salida ... sin embargo, podría usar head100000 pero para "búsqueda informal de proyectos / directorios", este enfoque funciona muy bien para mí.


Primero no necesita usar cat para contar líneas. Este es un antipatrón llamado Uso Inútil del Gato (UUoC). Para contar líneas en archivos en el directorio actual, use wc :

wc -l *

Entonces el comando find repite los subdirectorios:

find . -name "*.c" -exec wc -l {} /;

  • . es el nombre del directorio superior para comenzar a buscar desde

  • -name "*.c" es el patrón del archivo que le interesa

  • -exec da un comando para ser ejecutado

  • {} es el resultado del comando find para pasar al comando (aquí wc-l )

  • /; indica el final del comando

Este comando produce una lista de todos los archivos encontrados con su recuento de líneas, si desea tener la suma de todos los archivos encontrados, puede usar find para listar los archivos (con la opción -print ) y luego usar xargs para pasar esta lista como argumento para wc-l.

find . -name "*.c" -print | xargs wc -l

EDITAR para abordar el comentario de Robert Gamble (gracias): si tiene espacios o líneas nuevas (!) En nombres de archivos, entonces tiene que usar la opción -print0 lugar de -print y xargs -null para que la lista de nombres de archivos se intercambie con null -cadenas terminadas.

find . -name "*.c" -print0 | xargs -0 wc -l

La filosofía de Unix es tener herramientas que solo hagan una cosa y que lo hagan bien.


Si desea generar solo un recuento total de líneas y no un recuento de líneas para cada archivo, por ejemplo:

find . -type f -exec wc -l {} /; | awk ''{total += $1} END{print total}''

funciona bien. Esto le ahorra la necesidad de hacer más filtrado de texto en un script.


Si quieres una respuesta de código de golf:

grep '''' -R . | wc -l

El problema con solo usar wc -l por sí solo es que no puede descender bien, y los onelineros usan

find . -exec wc -l {} /;

No le dará un recuento total de líneas porque se ejecuta wc una vez por cada archivo, (loL!) Y

find . -exec wc -l {} +

Se confundirá tan pronto como encuentre coincidencias con el límite de argumento de ~ 200k 1 , 2 caracteres para los parámetros y, en su lugar, invoque a wc varias veces, y cada vez solo obtendrá un resumen parcial.

Además, el truco grep anterior no agregará más de 1 línea a la salida cuando se encuentre con un archivo binario, lo que podría ser beneficioso desde el punto de vista circunstancial.

Por el costo de 1 personaje de comando adicional, puede ignorar por completo los archivos binarios:

grep '''' -IR . | wc -l

Si desea ejecutar conteos de líneas en archivos binarios también

grep '''' -aR . | wc -l Nota al pie sobre los límites:

Los documentos son un poco imprecisos en cuanto a si es un límite de tamaño de cadena o un número de tokens límite.

cd /usr/include; find -type f -exec perl -e ''printf qq[%s => %s/n], scalar @ARGV, length join q[ ], @ARGV'' {} + # 4066 => 130974 # 3399 => 130955 # 3155 => 130978 # 2762 => 130991 # 3923 => 130959 # 3642 => 130989 # 4145 => 130993 # 4382 => 130989 # 4406 => 130973 # 4190 => 131000 # 4603 => 130988 # 3060 => 95435

Esto implica que se va a cortar muy fácilmente.


Usar cat o grep en las soluciones anteriores es un desperdicio si puede usar herramientas GNU relativamente recientes, incluido Bash:

wc -l --files0-from=<(find . -name /*.c -print0)

Esto maneja los nombres de archivos con espacios, recursiones arbitrarias y cualquier cantidad de archivos coincidentes, incluso si exceden el límite de longitud de línea de comando.


find . -name "*.h" -print | xargs wc -l


wc -cl `find . -name "*.php" -type f`