grep, pero solo ciertas extensiones de archivo

966

Estoy trabajando en escribir algunos scripts en grepciertos directorios, pero estos directorios contienen todo tipo de tipos de archivos.

Quiero grepsolo .hy .cpppor ahora, pero tal vez algunos otros en el futuro.

Hasta ahora tengo:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP [email protected]

¿Alguien puede mostrarme cómo agregaría ahora solo las extensiones de archivo específicas?

Jason
fuente
13
Intentado grep -r -i CP_Image ~/path1/*.{h,cpp}?
8
Utilice La Plata Buscador : ag -i CP_Image ~/path[1-5] | mailx -s GREP [email protected]. Trabajo hecho.
Johnsyweb
Use egrep (lo más probable es que esté preinstalado en su sistema), y luego puede usar una expresión regular.
Dogweather
8
Los chicos de GNU muy mal estado cuando se añadió -ra greptener que buscar archivos como que rompe el mantra UNIX de contar con herramientas que "hacer una cosa y hacerlo bien". Hay una herramienta perfectamente buena para encontrar archivos con un nombre MUY obvio.
Ed Morton

Respuestas:

1354

Simplemente use el --includeparámetro, así:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP [email protected]

eso debería hacer lo que quieras.

Para tomar la explicación de la respuesta de HoldOffHunger a continuación:

  • grep: comando

  • -r: recursivamente

  • -i: ignorar caso

  • --include \*.cpp: todos * .cpp: archivos C ++ (escape con \ solo en caso de que tenga un directorio con asteriscos en los nombres de archivo)

  • ./: Comience en el directorio actual.

Nelson
fuente
123
Para el registro: -r (recursivo) -i (ignorar mayúsculas y minúsculas) --incluir (buscar solo archivos que coincidan con el patrón de archivo)
Luis
34
Se puede optimizar aún más paragrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol
1
@Hong, ¿dónde está la documentación de que -R es para enlaces simbólicos?
titus
8
Este ejemplo parece tener un puntaje alto porque cubre una gama tan amplia de posibilidades, pero la respuesta dada a continuación de grep -r --include = *. Txt 'searchterm' ./ realmente explica la esencia de la respuesta
David Casper
10
¿por qué no usar comillas dobles en lugar de barra invertida? por ejemplo:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda
283

Algunas de estas respuestas parecían demasiado cargadas de sintaxis o producían problemas en mi servidor Debian. Esto funcionó perfectamente para mí:

Revolución PHP: ¿Cómo Grep archivos en Linux, pero solo ciertas extensiones de archivo?

A saber:

grep -r --include=\*.txt 'searchterm' ./

... o versión que no distingue entre mayúsculas y minúsculas ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: comando

  • -r: recursivamente

  • -i: ignorar caso

  • --include: todos * .txt: archivos de texto (escape con \ solo en caso de que tenga un directorio con asteriscos en los nombres de archivo)

  • 'searchterm': Qué buscar

  • ./: Comience en el directorio actual.

HoldOffHunger
fuente
77
Debes escapar del *uso de \*.cppo '*.cpp'. De lo contrario, no dará el resultado esperado cuando el directorio de trabajo contenga algunos *.txtarchivos.
Melebius el
@Melebius, ¿puede explicar por qué necesita escapar? ¿Tiene algo que ver con las extensiones CPP o TXT que mencionó? ¿O simplemente los usaste como ejemplos?
Simon East
2
@SimonEast Estas extensiones son las que se usan en esta pregunta y respuesta, de lo contrario, nada especial. Probablemente funcionaría sin escapar cuando se usa, --include=<pattern>pero es importante escapar *con --include <pattern>(un espacio en lugar de =) que de lo contrario se siente muy similar.
Melebius
52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./
Yuri Malov
fuente
3
grep -rn "algo para grep" --include = *. {module, inc, c, h} *
ashish el
3
Buena respuesta. Más limpio que el aceptado en la OMI, pero debe agregar criterios de búsqueda como señaló
@ashish
¿Por qué la --includeopción después de la aguja, no con otras opciones?
vladkras
@vladkras, ¿qué quieres decir con aguja? Es --?
presente
50

Qué tal si:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print
Amir Afghani
fuente
55
Sugeriría agrupar esos -nameargumentos. cosas extrañas pueden suceder si no lo haces. find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution
use con "-type f" adicional para ignorar todos los objetos de directorio, solo interesados ​​en archivos.
kensai
1
Utilicé este método durante años y funciona, pero es MUCHO más lento que grep recursivo ya que el exec de find genera un proceso grep separado para cada archivo que se busca.
beaudet
Abordar el comentario de @ beaudet, findopcionalmente puede agrupar argumentos, reduciendo al mínimo las invocaciones del proceso llamado. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Esto se sugiere pero no se destaca en la respuesta de @ fedorqui a continuación y es una mejora que vale la pena. El -Hargumento para grep aquí es útil cuando find solo identifica un único archivo coincidente. Esto podría eliminar el uso de -printen la respuesta. Si su lista total de archivos es lo suficientemente pequeña, {path1,path2}/**/*.{cpp,h}puede ser preferible usar un globo de shell recursivo (por ejemplo ).
Malcolm
19

No hay una opción -r en los servidores HP y Sun, de esta manera funcionó para mí en mi servidor HP

find . -name "*.c" | xargs grep -i "my great text"

-i es para búsqueda de cadena sin distinción entre mayúsculas

Sam B
fuente
1
Me he encontrado con varios servidores para empresas de alojamiento web que no tienen la opción --incluir disponible para fgrep y esta es la línea de comando que uso en esos casos.
Borgboy
La opción --include tampoco está disponible cuando se usa Git para Windows (MinGW / MSys).
Darren Lewis el
@DarrenLewis disponible en Git Bash para Windows. Pero extrañamente, agrega alias coloridos como llpero no se agrega --color=autoa grep.
Xeverous
¡Esta debería ser la respuesta aceptada para completar, portabilidad y brevedad!
Grant Foster, el
12

Como se trata de encontrar archivos, find¡ usemos !

Con GNU find puede usar la -regexopción para buscar esos archivos en el árbol de directorios cuya extensión es .ho .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Entonces, solo es cuestión de ejecutar grepcada uno de sus resultados:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Si no tiene esta distribución de hallazgo, debe usar un enfoque como el de Amir Afghani , usar -opara concatenar opciones ( el nombre termina con .ho con.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Y si realmente quiere usar grep, siga la sintaxis indicada para --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^
fedorqui 'así que deja de dañar'
fuente
7

La forma más fácil es

find . -type  f -name '*.extension' | xargs grep -i string 
usuario3640130
fuente
3

ag (el buscador plateado) tiene una sintaxis bastante simple para esto

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

entonces

ag -G *.h -G *.cpp CP_Image <path>
Eldamir
fuente
usando ag 2.2.0, necesitaba poner mis banderas al final:ag _string_to_find_ -G _filename_regex_
ryanrain
3

La siguiente respuesta es buena:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP [email protected]

Pero se puede actualizar a:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP [email protected]

Que puede ser más simple.

hao
fuente
1

Debería escribir "-exec grep" para cada "-o -name"

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

O agrúpelos por ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

La opción '-Hn' muestra el nombre del archivo y la línea.

donde23
fuente
1

Soy consciente de que esta pregunta está un poco anticuada, pero me gustaría compartir el método que normalmente uso para encontrar archivos .c y .h :

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

o si necesita el número de línea también:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
Tom
fuente