Estoy buscando la cadena foo=
en archivos de texto en un árbol de directorios. Está en una máquina Linux común, tengo bash shell:
grep -ircl "foo=" *
En los directorios también hay muchos archivos binarios que coinciden con "foo =". Como estos resultados no son relevantes y ralentizan la búsqueda, quiero que grep omita la búsqueda de estos archivos (principalmente imágenes JPEG y PNG). ¿Como podría hacerlo?
Sé que existen las opciones --exclude=PATTERN
y --include=PATTERN
, pero ¿cuál es el formato del patrón? La página del manual de grep dice:
--include=PATTERN Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN Recurse in directories skip file matching PATTERN.
Buscando en grep include , grep include exclude , grep exclude y variantes no encontró nada relevante
Si hay una mejor manera de grepping solo en ciertos archivos, estoy de acuerdo; mover los archivos ofensivos no es una opción. No puedo buscar solo ciertos directorios (la estructura del directorio es un gran desastre, con todo en todas partes). Además, no puedo instalar nada, así que tengo que ver con herramientas comunes (como grep o el hallazgo sugerido ).
--exclude-dir=.svn
, por lo que grep no entra en ellos en absolutogrep -r --exclude-dir=var "pattern" .
Respuestas:
Use la sintaxis de shell globbing:
La sintaxis para
--exclude
es idéntica.Tenga en cuenta que la estrella se escapa con una barra invertida para evitar que el shell la expanda (citarla, por ejemplo
--include="*.{cpp,h}"
, funcionaría igual de bien). De lo contrario, si tuviera algún archivo en el directorio de trabajo actual que coincidiera con el patrón, la línea de comando se expandiría a algo así comogrep pattern -r --include=foo.cpp --include=bar.h rootdir
, que solo buscaría archivos con nombrefoo.cpp
ybar.h
, lo que probablemente no sea lo que deseaba.fuente
grep pattern -r --include="*.{cpp,h}" rootdir
grep pattern -r --include=foo.cpp --include=bar.h rootdir
, que solo buscará archivos nombradofoo.cpp
obar.h
. Si no tiene ningún archivo que coincida con el glob en el directorio actual, el shell pasa el glob a grep, que lo interpreta correctamente.--exclude-dir
opción. Sin embargo, se aplican las mismas reglas. Solo el nombre de archivo del directorio coincide, no una ruta.--include
No parece funcionar después--exclude
. Supongo que no tiene sentido ni siquiera intentarlo, excepto que tengoalias
que lidiar con una larga lista de--exclude
y--exclude-dir
, que uso para buscar código, ignorando bibliotecas e intercambiando archivos y cosas. Me hubiera esperado quegrep -r --exclude='*.foo' --include='*.bar'
iba a funcionar, por lo que podría limitar mialias
a--include='*.bar'
solamente, pero parece ignorar el--include
e incluyen todo lo que no es un archivo .foo. Cambiar el orden de los--include
y--exclude
funciona, pero, por desgracia, eso no es útil para mialias
.PATTERN
? Media hora no puedo encontrar ninguna descripción de lo que están esperando allíSi solo quiere omitir archivos binarios, le sugiero que mire la
-I
opción (mayúscula i). Ignora los archivos binarios. Regularmente uso el siguiente comando:Busca de forma recursiva, ignora los archivos binarios y no busca dentro de las carpetas ocultas de Subversion, para cualquier patrón que desee. Lo tengo alias como "grepsvn" en mi caja en el trabajo.
fuente
--exclude-dir
No está disponible en todas partes. mi caja RH en el trabajo con GNU grep 2.5.1 no lo tiene.--exclude-dir
no está disponible? En todos mis intentos,--exclude
no parece ajustarse a la factura.--exclude-dir="\.git"
. :-)Eche un vistazo a ack , que está diseñado para exactamente estas situaciones. Tu ejemplo de
se hace con ack como
porque ack nunca busca en archivos binarios de forma predeterminada, y -r está activado de forma predeterminada. Y si solo quieres archivos CPP y H, entonces solo haz
fuente
apt-get
en Ubuntu :)awk
grep 2.5.3 introdujo el parámetro --exclude-dir que funcionará de la manera que desee.
También puede establecer una variable de entorno: GREP_OPTIONS = "- exclude-dir = .svn"
Voy a segundo de Andy voto para ACK sin embargo, es la mejor.
fuente
Encontré esto después de mucho tiempo, puede agregar múltiples inclusiones y exclusiones como:
fuente
El comando sugerido:
es conceptualmente incorrecto, porque --exclude funciona en el nombre base. En otras palabras, se saltará solo el .svn en el directorio actual.
fuente
En grep 2.5.1 debe agregar esta línea al perfil ~ / .bashrc o ~ / .bash
fuente
Encuentro que la salida de grepping grep es muy útil a veces:
Sin embargo, eso en realidad no impide que busque en los archivos binarios.
fuente
grep -I
para omitir archivos binarios.Si no eres reacio a usar
find
, me gusta su-prune
característica:En la primera línea, especifique el directorio que desea buscar.
.
(directorio actual) es una ruta válida, por ejemplo.En la 2ª y 3ª líneas, uso
"*.png"
,"*.gif"
,"*.jpg"
, y así sucesivamente. Use tantas de estas-o -name "..." -prune
construcciones como tenga patrones.En la cuarta línea, necesita otro
-o
(especifica "o" afind
), los patrones que SI desea, y necesita uno-print
o-print0
al final. Si lo que desea es "todo lo demás" lo que queda después de la poda del*.gif
,*.png
, etc. imágenes, a continuación, utilizar-o -print0
y que haya terminado con la cuarta línea.Finalmente, en la quinta línea está la tubería a la
xargs
que toma cada uno de esos archivos resultantes y los almacena en una variableFILENAME
. Luego pasagrep
las-IR
banderas,"pattern"
y luegoFILENAME
se expandexargs
para convertirse en esa lista de nombres de archivo encontrados porfind
.Para su pregunta en particular, la declaración puede verse algo así como:
fuente
-false
inmediatamente después de cada uno,-prune
así que olvidarse de usar-print0
o algún tipo deexec
comando en realidad no imprimirá los archivos que desea excluir:-name "*.png" -prune -false -o name "*.gif -prune -false
...En CentOS 6.6 / Grep 2.6.3, tengo que usarlo así:
Note la falta de igualdad de signos "=" (de lo contrario
--include
,--exclude
,include-dir
y--exclude-dir
son ignorados)fuente
git grep
Uso
git grep
que está optimizado para el rendimiento y tiene como objetivo buscar a través de ciertos archivos.Por defecto ignora los archivos binarios y está honrando su
.gitignore
. Si no está trabajando con la estructura de Git, aún puede usarla pasando--no-index
.Ejemplo de sintaxis:
Para más ejemplos, ver:
fuente
Soy un diletante, claro, pero así es como se ve mi ~ / .bash_profile:
Tenga en cuenta que para excluir dos directorios, tuve que usar --exclude-dir dos veces.
fuente
Prueba este:
Fundado aquí: http://www.unix.com/shell-programming-scripting/42573-search-files-excluding-binary-files.html
fuente
Si busca de forma no recursiva, puede usar patrones glop para que coincidan con los nombres de archivo.
incluye html y txt. Busca solo en el directorio actual.
Para buscar en los subdirectorios:
En los subdirectorios:
fuente
ripgrep
Esta es una de las herramientas más rápidas diseñadas para buscar recursivamente su directorio actual. Está escrito en Rust , construido sobre el motor regex de Rust para una máxima eficiencia. Consulte el análisis detallado aquí .
Entonces puedes simplemente ejecutar:
Respeta
.gitignore
y omite automáticamente los archivos / directorios ocultos y los archivos binarios.Aún puede personalizar incluir o excluir archivos y directorios con
-g
/--glob
. Las reglas globales coinciden con los globales.gitignore
. Buscaman rg
ayuda.Para obtener más ejemplos, consulte: ¿Cómo excluir algunos archivos que no coinciden con ciertas extensiones con grep?
En macOS, puede instalar a través de
brew install ripgrep
.fuente
find y xargs son tus amigos. Úselos para filtrar la lista de archivos en lugar de grep's --exclude
Intenta algo como
La ventaja de acostumbrarse a esto es que se puede expandir a otros casos de uso, por ejemplo, para contar las líneas en todos los archivos que no son png:
Para eliminar todos los archivos que no son png:
etc.
Como se señaló en los comentarios, si algunos archivos pueden tener espacios en sus nombres, use
-print0
y en suxargs -0
lugar.fuente
esos scripts no logran todo el problema ... Intente esto mejor:
este script es mucho mejor, porque usa expresiones regulares "reales" para evitar la búsqueda de directorios. simplemente separe los nombres de carpeta o archivo con "\ |" en el grep -v
¡disfrútala! encontrado en mi shell de Linux! XD
fuente
Mira @ este.
fuente
La
--binary-files=without-match
opción de GNUgrep
hace que omita los archivos binarios. (Equivalente al-I
cambio mencionado en otra parte).(Esto puede requerir una versión reciente de
grep
; 2.5.3 lo tiene, al menos).fuente
adecuado para tcsh .alias archivo:
Me tomó un tiempo descubrir que la porción {mm, m, h, cc, c} NO debería estar entre comillas. ~ Keith
fuente
Para ignorar todos los resultados binarios de grep
La parte awk filtrará todos los archivos binarios para que coincidan las líneas
fuente
Prueba esto:
--F
" debajo de currdir .. (o vincule otra carpeta allí renombrada como "--F
" es decirdouble-minus-F
.#> grep -i --exclude-dir="\-\-F" "pattern" *
fuente