Tengo alrededor de 500 cadenas y quiero buscar los archivos que las contienen dentro de un directorio y obtener los nombres de los archivos que contienen las cadenas. Hasta ahora he estado usando:
find -name 'LYFNRE.*' -exec grep -f file1.txt {} \; -print
pero el problema es que se puede encontrar una cadena en muchos archivos, por lo que es difícil encontrar qué cadenas están presentes y cuáles faltan debido al enorme resultado. ¿Pueden ayudarme a imprimir las cadenas con sus correspondientes nombres de archivo donde se encontraron?
Respuesta1
Deberías dejar que grep
te proporcionen los nombres de los archivos. GNU grep
puede hacer esto:
grep -HFf ../strings.txt *
Eso le presentará un resultado similar a:
[filename]:[matched_line]
...para cada coincidencia en cada archivo del directorio. También puede obtener números de línea:
grep -HnFf ../strings.txt *
...que proporciona...
[filename]:[line_number]:[matched_line]
Respuesta2
El problema es que estás pasando un archivo a la vez a grep
. Cuando grep
ve un solo archivo en su línea de comando, asume que sabe exactamente dónde está buscando, por lo que no muestra el nombre del archivo delante de las coincidencias.
Un truco para forzar grep
la salida siempre de un nombre de archivo es pasar también /dev/null
(donde nunca habrá ninguna coincidencia). Algunas implementaciones de grep tienen una opción para eso: -H
.
Además, puede utilizar -exec … {} +
en lugar de -exec … {} \;
ejecutar el programa para muchos archivos a la vez. Esto es más rápido. Aún así debes pasar /dev/null
o -H
, porque podría suceder que el comando se invoque exactamente en un archivo, ya sea porque hay un único archivo coincidente o porque hay muchas coincidencias que requieren que grep
se invoque varias veces y una vez se refiere a un solo archivo.
find -name 'LYFNRE.*' -exec grep -f file1.txt /dev/null {} +
GNU grep y las implementaciones recientes de BSD (incluido OSX) admiten opciones para llamar grep
de forma recursiva sin necesidad de find
.
grep -R --include='LYFNRE.*' -f file1.txt -H .
Alternativamente, puedes hacer globbing recursivo en tu shell. En zsh, esto funciona de inmediato. En bash, primero debe ejecutarlo shopt -s globstar
y tenga en cuenta que bash se repite a través de enlaces simbólicos a directorios (a diferencia de find
o zsh).
grep -f file1.txt /dev/null **/LYFNRE.*
Respuesta3
utilizar egrep:
egrep -n "str1|str2|str3" file_names
-n imprimirá el número de línea en el archivo específico donde se encontró la cadena