Encontrar archivos que contienen una cadena determinada usando find (1) y grep (1)

70

find . -type f -print -exec cat {} \; | grep some string

El comando anterior no imprime la ruta del archivo.

Estoy usando: Ubuntu, bash 4.

H.Rabiee
fuente
Tal vez no cumple con los resultados esperados debido al filtro grep. ¿Qué hay de esto:find . -type f -fprint /dev/stderr -exec cat {} \; | grep some string
artistoex
¿Cuál es el objetivo que quieres lograr? En la salida, está obteniendo cadenas asimiladas de los archivos, ¿desea la ruta de esos archivos?
mirkobrankovic
Sí, quiero imprimir la ruta de los archivos que contienen la cadena 'alguna cadena'. La sugerencia @artistoex imprime todas las rutas de archivo.
H.Rabiee
Es posible que simplemente desee utilizar ackpara examinar todos los archivos en el directorio actual, posiblemente filtrando solo en ciertos tipos de archivos.
Jaap Eldering

Respuestas:

87

Eso es porque estás alimentando grepuna secuencia de texto que simplemente contiene nombres de archivos. Como no proporcionó nombres de archivo como argumentos para grep, no se puede esperar que deduzca de qué archivo proviene una línea coincidente. Uso xargs:

find . -type f -print | xargs grep "some string"

Como tiene GNU find / xargs, esta es una forma más segura para que xargs lea los nombres de archivo:

find . -type f -print0 | xargs -0 grep "some string"

Si solo desea los nombres de archivo que tienen una línea coincidente sin mostrar la línea coincidente:

find . -type f -print0 | xargs -0 grep -l "some string"
Glenn Jackman
fuente
¿Cómo combinaría los comandos anteriores con buscar y reemplazar? Como en grep entonces sed?
CMCDragonkai
1
la canalización find | grep genera nombres de archivo, por lo tanto:sed '...' $(find ... | xargs grep -l ...)
glenn jackman
107

yo suelo

grep "some string" . -R

y funciona más rápido

PD

Caso de uso más complejo

grep -HiRE "some string|other string" . #H for file printing, i for case-insensitive, R for recursive search, E for regex 

Para leer param i explicación

grep --help | grep -- -i
ArcherGodson
fuente
17
Y -nsi quieres números de línea. +1 para respuesta simplificada.
Chad Skeeters
@ChadSkeeters exactamente. Usar el hallazgo no da tal solución.
ArcherGodson
1
Esto debe ser marcado como la respuesta correcta, para ser honesto. El seleccionado actualmente detalla algo completamente diferente.
12

A menudo busco código fuente en estructuras de carpetas complejas y me resulta útil usar:

cd /your/folder/
grep -rHino "your string"

Con esos parámetros, sin usar find , obtengo la ruta completa del archivo y el número de línea que contiene la cadena especificada .

También es fácil de recordar porque BASH es a través de tu búsqueda como un rinoceronte :)

Mostraré cómo funciona esto con un ejemplo rápido.

Vamos a mostrar el contenido de un archivo usando cat:

jeeves ~ # cat fw.stop
#!/bin/sh
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Y busquemos recursivamente todos los archivos que contienen la cadena "iptables -P":

jeeves ~ # grep -rinHo "iptables -P"
fw.stop:9:iptables -P
fw.stop:10:iptables -P
fw.stop:11:iptables -P

Como puede ver en la salida tenemos el nombre del archivo: fila de hit: cadena buscada

Aquí hay una descripción más detallada de los parámetros utilizados:

-r Para cada operando de directorio, lea y procese todos los archivos en ese directorio, de forma recursiva. Siga los enlaces simbólicos en la línea de comando, pero omita los enlaces simbólicos que se encuentran recursivamente. Tenga en cuenta que si no se proporciona ningún operando de archivo, grep busca en el directorio de trabajo. Esto es lo mismo que la opción '--directories = recurse'.

-i Imprime el nombre del archivo para cada partido. Este es el valor predeterminado cuando hay más de un archivo para buscar.

-n Prefije cada línea de salida con el número de línea basado en 1 dentro de su archivo de entrada. (-n está especificado por POSIX).

-H Imprime el nombre del archivo para cada partido. Este es el valor predeterminado cuando hay más de un archivo para buscar.

-o Imprima solo las partes coincidentes (no vacías) de las líneas coincidentes, con cada parte en una línea de salida separada. Las líneas de salida usan los mismos delimitadores que la entrada, y los delimitadores son bytes nulos si también se usa -z (--null-data) (consulte Otras opciones).

Pitto
fuente
2

Yo preferí

El | encontrar el archivo | hacer grep ont buscar archivo | muestra la ruta completa del archivo

find / -type f -exec grep 'alguna cadena' {} \; -exec echo {} \;

usuario515185
fuente
0

Silver Searcher es una utilidad muy rápida y práctica para buscar archivos y contenido.

Para resolver su problema, el comando del buscador plateado se vería así ...

ag 'some string' -l

-l Solo imprima nombres de archivo que contengan coincidencias (no imprima las líneas coincidentes)

qoomon
fuente