¿Encuentra archivos que contienen cadenas en el nombre del archivo y diferentes cadenas dentro del archivo?

17

Me gustaría encontrar (recursivamente) todos los archivos con "ABC" en su nombre de archivo, que también contienen "XYZ" en el archivo. Lo intenté:

find . -name "*ABC*" | grep -R 'XYZ'

pero no está dando la salida correcta.

usuario997112
fuente

Respuestas:

26

Esto se debe a grepque no se pueden leer los nombres de los archivos para buscar desde la entrada estándar. Lo que está haciendo es imprimir nombres de archivos que contienen XYZ. Utilice findla -execopción de en su lugar:

find . -name "*ABC*" -exec grep -H 'XYZ' {} +

De man find:

   -exec command ;
          Execute  command;  true  if 0 status is returned.  All following
          arguments to find are taken to be arguments to the command until
          an  argument  consisting of `;' is encountered.  The string `{}'
          is replaced by the current file name being processed  everywhere
          it occurs in the arguments to the command, not just in arguments
          where it is alone, as in some versions of find. 

[...]

   -exec command {} +
          This  variant  of the -exec action runs the specified command on
          the selected files, but the command line is built  by  appending
          each  selected file name at the end; the total number of invoca‐
          tions of the command will  be  much  less  than  the  number  of
          matched  files.   The command line is built in much the same way
          that xargs builds its command lines.  Only one instance of  `{}'
          is  allowed  within the command.  The command is executed in the
          starting directory.

Si no necesita las líneas coincidentes reales sino solo la lista de nombres de archivo que contienen al menos una aparición de la cadena, use esto en su lugar:

find . -name "*ABC*" -exec grep -l 'XYZ' {} +
terdon
fuente
2

Encuentro el siguiente comando de la manera más simple:

grep -R --include="*ABC*" XYZ

o agregar -ia mayúsculas y minúsculas:

grep -i -R --include="*ABC*" XYZ
R. Oosterholt
fuente
1

… | grep -R 'XYZ'No tiene sentido. Por un lado, -R 'XYZ'significa actuar recursivamente en el XYZdirectorio. Por otro lado, … | grep 'XYZ'significa buscar el patrón XYZen grepla entrada estándar de. \

En Mac OS X o BSD, grepse tratará XYZcomo un patrón y se quejará:

$ echo XYZ | grep -R 'XYZ'
grep: warning: recursive search of stdin
(standard input):XYZ

GNU grepno se quejará. Por el contrario, se trata XYZcomo un patrón, ignora su entrada estándar y realiza búsquedas recursivas a partir del directorio actual.


Lo que querías hacer era probablemente

find . -name "*ABC*" | xargs grep -l 'XYZ'

... que es similar a

grep -l 'XYZ' $(find . -name "*ABC*")

… Ambos le dicen grepque busque XYZen los nombres de archivo coincidentes.

Sin embargo, tenga en cuenta que cualquier espacio en blanco en los nombres de archivo hará que esos dos comandos se rompan. Puede usar de xargsforma segura utilizando NULcomo delimitador:

find . -name "*ABC*" -print0 | xargs -0 grep -l 'XYZ'

Pero la solución de @terdon usando find … -exec grep -l 'XYZ' '{}' +es más simple y mejor.

200_success
fuente
-1

Recomendación de Linux: ll -iR | grep "nombre de archivo"

Ej: Bookname.txt luego use ll -iR | grep "Nombre del libro" o ll -iR | grep "nombre" o ll -iR | grep "Libro"

podemos buscar con parte del nombre del archivo.

Esto mostrará una lista de todos los nombres de archivos que coinciden con las carpetas actuales y sub

Periya Samy
fuente
Esta es solo una respuesta parcial, ya que nunca aborda la parte de "pregunta dentro del archivo" de la pregunta. También es mucho más eficiente usar patrones globales de nombres de archivo, posiblemente en combinación con lo findque se muestra en algunas de las otras respuestas.
Kusalananda