¿Cómo puedo "grep" filtrar recursivamente el nombre de los archivos que quiero con comodines?

40

Cuando quiero realizar una búsqueda grep recursiva en el directorio actual, generalmente hago:

grep -ir "string" .

Pero ese comando busca dentro de todo tipo de archivos, incluidos los archivos binarios (imágenes, audio, video, etc.), lo que resulta en un proceso de búsqueda muy lento.

Si hago esto, por ejemplo, no funciona:

grep -ir "string" *.php

No funciona porque no hay archivos PHP dentro del directorio actual, sino dentro de algunos de los subdirectorios en el directorio actual, y los nombres de los subdirectorios no terminan con ".php", por lo que grep no mira dentro de ellos.

Entonces, ¿cómo puedo hacer una búsqueda recursiva desde el directorio actual pero también especificando comodines de nombre de archivo? (es decir: solo busca en archivos que terminan en una extensión específica)

OMA
fuente

Respuestas:

58

Use grepla --includeopción:

grep -ir "string" --include="*.php" .
Dan D.
fuente
1
Ok, parece que mi versión de grep era antigua, porque no tenía esa opción (¡no es de extrañar por qué no pude descubrir cómo hacer esto!). Recibí el mensaje: "grep: opción no reconocida` --include = *. Php '". Pero acabo de actualizar a uno más nuevo y ahora funciona. ¡Gracias!
OMA
Tuve que reemplazar el período al final y usar:grep -ir "string" --include="*.php" *
Stuart
¡Pensé que punto era solo el final de la línea! No lo usé ni lo necesité.
Boardtc
14

Si tiene una versión grepque carece de la --includeopción, puede usar lo siguiente. Ambos fueron probados en una estructura de directorios como esta:

$ tree
.
├── a
├── b
   └── foo2.php
├── c
   └── d
       └── e
           └── f
               └── g
                   └── h
                       └── foo.php
├── foo1.php
└── foo.php

Donde todos los .phparchivos contienen la cadena string.

  1. Utilizar find

    $ find . -name '*php' -exec grep -H string {} +
    ./b/foo2.php:string
    ./foo1.php:string
    ./c/d/e/f/g/h/foo.php:string

    Explicación

    Esto encontrará todos los .phparchivos y luego se ejecutará grep -H stringen cada uno de ellos. Con findla -execopción 's , {}se reemplaza por cada uno de los archivos encontrados. Le -Hindica grepque imprima el nombre del archivo y la línea coincidente.

  2. Suponiendo que tiene una versión suficientemente nueva de bash, use globstar:

    $ shopt -s globstar
    $ grep -H string  **/*php
    b/foo2.php:string
    c/d/e/f/g/h/foo.php:string
    foo1.php:string

    Explicación

    Como se explica en el manual de bash :

    Globstar

    Si se establece, el patrón '**' utilizado en un contexto de expansión de nombre de archivo coincidirá con todos los archivos y cero o más directorios y subdirectorios. Si el patrón es seguido por un '/', solo coinciden los directorios y subdirectorios.

    Entonces, al ejecutar shopt -s globstar, está activando la función y la globstaropción de Bash que hace que se **/*phpexpanda a todos los .phparchivos en el directorio actual ( **coincide con 0 o más directorios, también **/*phpcoincide ./foo.php) que luego se seleccionan string.

terdon
fuente
-2

Utilizar */*.php

Esto hace que grep search sea un nivel de subdirectorio

Dennis Nolan
fuente
Algo salió mal cuando desaparecieron los asteriscos y los puntos.
Dennis Nolan
Puede usar las teclas de retroceso para formatear el código y evitar la ambigüedad sobre el uso de asteriscos para enfatizar el formato de rebajas. PD: la pregunta se refiere a "búsqueda recursiva" en el párrafo final (aunque no es mi voto negativo).
RedGrittyBrick
No es una respuesta correcta, porque solo es bueno para estructuras de directorio profundo de un nivel, como mencionas, pero aún así es bueno saberlo;). Mi voto a favor por eso.
OMA