Usé esto mucho, la mejora que trato de lograr es evitar nombres de archivos de eco que no coinciden en grep. ¿Mejor forma de hacer esto?

 for file in `find . -name "*.py"`; do echo $file; grep something $file; done 

Comentarios

Respuesta

 find . -name "*.py" -exec grep something {} \; -print  

imprimiría el nombre del archivo después de las líneas coincidentes.

 find . -name "*.py" -exec grep something /dev/null {} +  

imprimiría el nombre del archivo delante de cada línea coincidente (agregamos /dev/null para el caso en el que solo haya una archivo coincidente como grep no imprime el nombre del archivo si solo se ha pasado un archivo para buscar. La implementación GNU de grep tiene una -H opción para eso como alternativa).

 find . -name "*.py" -exec grep -l something {} +  

imprimiría solo los nombres de archivo de los archivos que tienen al menos una línea coincidente.

Para imprimir el nombre del archivo antes de las líneas coincidentes, puede usar awk en su lugar:

 find . -name "*.py" -exec awk " FNR == 1 {filename_printed = 0} /something/ { if (!filename_printed) { print FILENAME filename_printed = 1 } print }" {} +  

O llame a grep dos veces para cada archivo, aunque eso «sería menos eficiente ya que ejecutaría al menos un comando grep y hasta dos para cada archivo (y leería el contenido del archivo dos veces ):

 find . -name "*.py" -exec grep -l something {} \; \ -exec grep something {} \;  

En cualquier caso, no desea recorrer la salida de find así y recuerde citar su variables .

Si desea utilizar un ciclo de shell, con herramientas GNU:

 find . -name "*.py" -exec grep -l --null something {} + | xargs -r0 sh -c " for file do printf "%s\n" "$file" grep something < "$file" done" sh  

(también funciona en FreeBSD y derivados).

Respuesta

I Si está usando GNU grep, puede usar su opción -r o --recursive para hacer esta búsqueda simple por usted:

 grep -r --include "*.py" -le "$regexp" ./ # for filenames only grep -r --include "*.py" -He "$regexp" ./ # for filenames on each match  

Solo necesita find si lo necesita predicados más avanzados.

Comentarios

  • Dependiendo de la versión de GNU grep, grep puede o no mirar dentro de enlaces simbólicos o atravesar enlaces simbólicos a directorios. También puede encontrar algunas variaciones en el manejo de otros tipos de archivos no regulares.

Responder

Usted puede decirle a grep que incluya el nombre del archivo en la salida. Entonces, si hay una coincidencia, se mostrará en la consola; si no hay ninguna coincidencia dentro de un archivo, no se imprimirá ninguna línea para ese archivo.

find . -name "*.py" | xargs grep -n -H something 

Desde man grep:

-H Always print filename headers with output lines -n, --line-number Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed. This option is ignored if -c, -L, -l, or -q is specified. 

Si sus archivos pueden tener nombres con espacios, debe cambiar la tubería para usar caracteres NUL como separador. El comando completo ahora se verá así:

find . -name "*.py" -print0 | xargs -0 grep -n -H something 

Responder

Puede intente algo como:

find . -name "*.py:" -exec grep -l {} \; 

Este comando exec grep para cada archivo, descubierto por el comando de búsqueda y su función de comando de búsqueda estándar

Respuesta

Utilice el argumento -l.

for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done 

Un uso más interesante sería:

for file in $(find . -name "*.py" -exec grep -l something "{}" +); do echo "$file"; grep something $file; done 

Responder

Allí son grep alternativas que, por defecto, muestran sus resultados en el formato que desee. Los 2 más populares que conozco son ag (también conocido como «el buscador de plata») y ack. ag se anuncia como una alternativa más rápida a ack.

$ ag "^\w+\s*\w+\(" ~/build/i3/src build/i3/src/display_version.c 58:void display_running_version(void) { build/i3/src/load_layout.c 42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings = 518:json_content_t json_determine_content(const char *filename) { 575:void tree_append_json(Con *con, const char *filename, char **errormsg) { build/i3/src/x.c 64:CIRCLEQ_HEAD(state_head, con_state) state_head = 67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head = 70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head = 97:void x_con_init(Con *con, uint16_t depth) { ... 

No puedo mostrarte aquí, pero la salida está bien coloreada. Obtengo los nombres de archivo en verde oliva, los números de línea en amarillo dorado y la pieza correspondiente en cada línea en rojo sangre. Sin embargo, los colores son personalizables.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *