Quiero excluir el archivo ./test/main.cpp
de mi búsqueda.
Esto es lo que estoy viendo:
$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern
Sé que es posible obtener el resultado que quiero mediante el uso de múltiples comandos en una disposición de tuberías y filtros, pero ¿hay alguna cita / escape que haga grep
comprender lo que quiero de forma nativa?
command-line
grep
sin bar
fuente
fuente
--exclude-dir
). Es por eso que me gustaría hacer que grep realice la exclusión de forma nativa.Respuestas:
grep
no puede hacer esto para el archivo en un directorio determinado si tiene más archivos con el mismo nombre en diferentes directorios, use find en su lugar:find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+
fuente
\!
y\+
? Parece funcionar bien sin las barras invertidas.grep
no se puede hacer esto, usefind
en su lugar" - perfecto.No creo que sea posible con GNU
grep
. Sin embargo, no necesitas tuberías.Con
find
:Con
zsh
:(excluye archivos ocultos, así como excluir .git, .svn ...).
fuente
Podría escribir un libro: "El arte perdido de
xargs
". Losfind ... -exec … ';
lanzamientos de un grep para cada archivo (pero con la variante de-exec … +
que no lo hace). Bueno, estamos desperdiciando ciclos de CPU en estos días, así que ¿por qué no? Pero si el rendimiento, la memoria y la potencia son un problema: use xargs:De GNU
find
's-print0
seNUL
termine los su producción yxargs
'-0
honores opción ese formato como entrada. Esto garantiza cualquier personaje divertido que tenga su archivo, la tubería no se confundirá. La-r
opción asegura que no haya errores en caso de quefind
no encuentre nada.Tenga en cuenta que ahora puede hacer cosas como:
GNU grep's
-z
hace lo mismo que xargs '-0
.fuente
find -exec (cmd) {} +
funciona igualxargs
yfind -exec (cmd) {} \;
funciona igual quexargs -n1
. En otras palabras, su declaración solo es correcta si\;
se utiliza la versión.xargs
es menos eficiente que el uso-exec … +
(aunque marginalmente). Ninguna de las respuestas aquí mencionan-exec … \;
.-exec ... +
agregado en enero de 2005. Sí, no estoy desactualizado ... en absoluto.Si su
find
soporte-path
fue agregado a POSIX en 2008 pero aún falta en Solaris:fuente
-path
no es POSIX?Para el registro, aquí está el enfoque que prefiero:
Al mantener el
grep
principio del comando, creo que esto es un poco más claro, además no deshabilitagrep
el resaltado de color. En cierto sentido, usarfind
una sustitución de comandos es solo una forma de extender / reemplazar el subconjunto (limitado) de búsqueda de archivos degrep
la funcionalidad de.Para mí, la
find -exec
sintaxis es algo arcana. Una complejidad confind -exec
es la (a veces) necesidad de escapar de varios caracteres (especialmente si\;
se usa en Bash). Solo para poner las cosas en contextos familiares, los siguientes dos comandos son básicamente equivalentes:Si desea excluir subdirectorios , puede ser necesario usar un comodín. No entiendo completamente el esquema aquí, habla sobre lo arcano :
Una nota más para generalizar
find
soluciones basadas en el uso en scripts :grep
la línea de comandos debe incluir la opción-H
/--with-filename
. De lo contrario, cambiará el formato de salida bajo la circunstancia de que solo haya un nombre de archivo en los resultados de búsquedafind
. Esto es notable porque no parece ser necesario si se usagrep
la búsqueda de archivos nativa (con la-r
opción).... Aún mejor, sin embargo, es incluir
/dev/null
como primer archivo para buscar. Esto resuelve dos problemas:grep
pensará que hay dos y usará el modo de salida de múltiples archivos.grep
pensará que hay un archivo y no se quedará esperando en stdin.Entonces la respuesta final es:
fuente
find
en una sustitución de comando. Esto se rompe si hay nombres de archivos que contienen espacios u otros caracteres especiales. Usofind -exec
, es robusto y fácil de usar.find -iname "*target*" -or -name 'exclude' -prune
. Bueno, de alguna manera funciona: el directorio podado se enumerará, pero no se buscará. Si no desea que! -name 'exclude'