Uno de mis comandos BASH favoritos es:
find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;
que busca el contenido de todos los archivos en y debajo del directorio actual para el SearchString especificado. Como desarrollador, esto ha sido útil a veces.
Sin embargo, debido a mi proyecto actual y la estructura de mi base de código, me gustaría hacer que este comando BASH sea aún más avanzado al no buscar ningún archivo que esté dentro o debajo de un directorio que contenga ".svn", o cualquier archivo que termina con ".html"
Sin embargo, la página de MAN para encontrar me confundió un poco. Intenté usar -prune, y me dio un comportamiento extraño. En un intento de omitir solo las páginas .html (para comenzar), intenté:
find . -wholename './*.html' -prune -exec grep 'SearchString' {} /dev/null \;
y no obtuve el comportamiento que esperaba. Creo que podría estar perdiendo el punto de -prune. podrían ustedes ayudarme?
Gracias
find
no es un comando bashgrep -rl 'SearchString'
find
para buscar dentro de un archivo.-name '*.*'
no encuentra todos los archivos: solo aquellos con un.
en su nombre (el uso de*.*
es típicamente un DOS-ismo, mientras que en Unix, normalmente se usa solo*
para eso). Para hacer coincidir realmente a todos, basta con retirar por completo el argumento:find . -exec ...
. O si solo desea aplicar grep a los archivos (y omitir directorios), entonces hágalofind . -type f -exec ...
.Respuestas:
Puede usar la función de negación (!) De buscar para no hacer coincidir archivos con nombres específicos:
Entonces, si el nombre termina en .html o contiene .svn en cualquier parte de la ruta, no coincidirá y, por lo tanto, no se ejecutará el archivo ejecutable.
fuente
*.*
coincidencia era garantizar que solo coincidiera con los archivos que contienen un.
? Find coincidirá con todos los archivos en ausencia de unaname
directiva, por lo que lo anterior coincidirá con todo excepto html y svn-wholename '*.svn*'
más que-name
..svn
directorios se excluyen de los resultados de búsqueda.! -name '.'
debería excluir.
de los resultados de búsqueda.He tenido el mismo problema durante mucho tiempo, y hay varias soluciones que pueden aplicarse en diferentes situaciones:
ack-grep
es una especie de "desarrolladorgrep
" que omite por defecto los directorios de control de versiones y los archivos temporales. Laman
página explica cómo buscar solo tipos de archivos específicos y cómo definir los suyos .grep
Las opciones--exclude
y las propias--exclude-dir
se pueden usar muy fácilmente para omitir archivos globales y directorios únicos (desafortunadamente, no es necesario buscar directorios).find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ...
debería funcionar, pero las opciones anteriores son probablemente menos problemáticas a largo plazo.fuente
El siguiente
find
comando elimina los directorios cuyos nombres contienen.svn
, aunque no desciende al directorio, el nombre de la ruta podada se imprime ... (¡-name '*.svn'
es la causa!) ..Puede filtrar los nombres de directorio a través de:
grep -d skip
que omite silenciosamente tales "nombres de directorio" de entrada.Con GNU grep, puede usar en
-H
lugar de/dev/null
. Como un pequeño problema secundario:\+
puede ser mucho más rápido que\;
, por ejemplo. para 1 millón de archivos de una línea, usarlo\;
tomó 4m20s , usarlo\+
solo tomó 1.2s .El siguiente método utiliza en
xargs
lugar de-exec
, y asume que no hay líneas nuevas\n
en ninguno de sus nombres de archivo . Como se usa aquí,xargs
es muy similar a encontrar\+
.xargs
puede pasar nombres de archivo que contienen espacios consecutivos cambiando el delimitador de entrada a'\n'
con la-d
opciónEsto excluye directorios cuyos nombres contienen
.svn
y greps solo archivos que no terminan en.html
.fuente
\+
variante de la acción -exec. ¡Hurra por problemas secundarios leves!+
que no es un carácter especial para el shell, no necesita escribir\
antes.