Te perdiste un ;(escapaste aquí \;para evitar que el shell lo interprete) o a +y a {}:
find . -exec grep chrome {} \;
o
find . -exec grep chrome {} +
findse ejecutará grepy sustituirá {}con los nombres de archivo encontrados. La diferencia entre ;y +es que con ;un solo grepcomando para cada archivo se ejecuta mientras que con +tantos archivos como sea posible se dan como parámetros a la grepvez.
Si usa el \; la construcción final grep se pasa un archivo a la vez, por lo que no muestra el nombre del archivo de forma predeterminada, solo las líneas coincidentes. Para obtener una lista de archivos, agregue el uso grep -lsdentro de la construcción de búsqueda.
Caleb
99
find . -exec grep foo {} +le mostrará una salida como esta./dir/file.py:from foo import bar
sg
10
find . -exec grep foo {} \;le mostrará una salida como estafrom foo import bar
sg
99
find . -exec grep -l foo {} +le mostrará una salida como esta./dir/file.py
sg
8
find . -exec grep -l foo {} \;le mostrará una salida como esta./dir/file.py
sg
46
No necesita usar findpara esto en absoluto; grep puede manejar la apertura de archivos desde una lista global de todo en el directorio actual:
grep chrome *
... o incluso recursivamente para la carpeta y todo lo que hay debajo:
grep se ahogará si la expansión supera ARG_MAX. -R visitará todo mientras usa find one puede agregar primitivas más fácilmente para excluir ciertos archivos (-name, etc.) o ni siquiera visitar subárboles (-prune).
Mel
66
Buenos puntos @Mel. Mi punto fue que, con toda probabilidad, la parte que preguntaba estaba haciendo las cosas más complejas de lo que debían ser al presentar findcuándo greppodría hacer el trabajo, pero en algunos casos sería más efectivo usar find para ajustar la lista de archivos antes de salir grep.
Caleb
44
@Mel grepno se ahoga en tal caso, execsí.
Chris Down
Funciona solo en caso de que todos los archivos estén en el mismo directorio, no cuando se distribuyen en subdirectorios.
Yaba
1
@Yaba Mi respuesta indica cómo manejar el caso de los archivos distribuidos en subdirectorios.
Caleb
18
find . | xargs grep 'chrome'
también puedes hacer:
find . | xargs grep 'chrome' -ls
El primero le muestra las líneas en los archivos, el segundo simplemente enumera los archivos.
La opción de Caleb es más ordenada, menos pulsaciones de teclas.
El problema con xargses que espera que su entrada sea citada de una manera peculiar que findno produce. Por find … | xargs …lo tanto , no funciona si tiene nombres de archivo que contienen espacios en blanco o \'".
Gilles
3
@Gilles Puede solucionar ese problema utilizando algo como find . | xargs -n1 -iX grep "X" 'chrome'para que los argumentos se alimenten uno a la vez y se citen. Obviamente, esta es una forma terriblemente ineficiente de manejar este ejemplo, pero para algunas situaciones es agradable.
Caleb
Para completar, también debemos mencionar la opción -i para la insensibilidad a mayúsculas y minúsculas con 'grep'. También hay -iname en find para mayúsculas y minúsculas.
Mateo
99
@Caleb: la única forma 100% confiable de hacer xargsfrente a los nombres de archivo de Linux es find ... -print0 | xargs -0usar NUL como separador. Alternativa: xargs -d '\n'usar la nueva línea como separador, 99% de confiabilidad.
Grawity
Utilizo esto a menudo, pero fallará para listas muy largas de nombres de archivo, en cuyo punto find -exec se convierte en el ganador.
Spacemoose
5
Encontrar es unidireccional y puedes probar, the_silver_searcherentonces todo lo que necesitas hacer es
ag chrome
Buscará Chrome en todos los archivos (incluidos los subdirectorios) y es más rápido que encontrar
También hay pt (buscador de platino, disponible en github.com/monochromegane/the_platinum_searcher ) que, en mi humilde opinión, hace el trabajo más rápido, puede que no importe si solo hay unos pocos archivos.
Esto busca de forma recursiva todos los archivos .py, y para cada archivo imprime el nombre de archivo y fgrep para 'hola' en ese archivo (para cada). La salida se ve así (solo ejecuté una hoy):
para no interferir con su flujo de trabajo, pero le gustaría: find . -name "*.py" -exec fgrep -l hello {} \; - imprimirá los nombres de los archivos que coinciden, y nada más
find: Only one instance of {} is supported with -exec ... +
-exec
confind
Respuestas:
Te perdiste un
;
(escapaste aquí\;
para evitar que el shell lo interprete) o a+
y a{}
:o
find
se ejecutarágrep
y sustituirá{}
con los nombres de archivo encontrados. La diferencia entre;
y+
es que con;
un sologrep
comando para cada archivo se ejecuta mientras que con+
tantos archivos como sea posible se dan como parámetros a lagrep
vez.fuente
grep -ls
dentro de la construcción de búsqueda.find . -exec grep foo {} +
le mostrará una salida como esta./dir/file.py:from foo import bar
find . -exec grep foo {} \;
le mostrará una salida como estafrom foo import bar
find . -exec grep -l foo {} +
le mostrará una salida como esta./dir/file.py
find . -exec grep -l foo {} \;
le mostrará una salida como esta./dir/file.py
No necesita usar
find
para esto en absoluto; grep puede manejar la apertura de archivos desde una lista global de todo en el directorio actual:... o incluso recursivamente para la carpeta y todo lo que hay debajo:
fuente
find
cuándogrep
podría hacer el trabajo, pero en algunos casos sería más efectivo usar find para ajustar la lista de archivos antes de salir grep.grep
no se ahoga en tal caso,exec
sí.también puedes hacer:
El primero le muestra las líneas en los archivos, el segundo simplemente enumera los archivos.
La opción de Caleb es más ordenada, menos pulsaciones de teclas.
fuente
xargs
es que espera que su entrada sea citada de una manera peculiar quefind
no produce. Porfind … | xargs …
lo tanto , no funciona si tiene nombres de archivo que contienen espacios en blanco o\'"
.find . | xargs -n1 -iX grep "X" 'chrome'
para que los argumentos se alimenten uno a la vez y se citen. Obviamente, esta es una forma terriblemente ineficiente de manejar este ejemplo, pero para algunas situaciones es agradable.xargs
frente a los nombres de archivo de Linux esfind ... -print0 | xargs -0
usar NUL como separador. Alternativa:xargs -d '\n'
usar la nueva línea como separador, 99% de confiabilidad.Encontrar es unidireccional y puedes probar,
the_silver_searcher
entonces todo lo que necesitas hacer esBuscará Chrome en todos los archivos (incluidos los subdirectorios) y es más rápido que encontrar
fuente
Para ver la lista de archivos en lugar de líneas:
o:
fuente
Aquí hay un ejemplo de cómo suelo usar find / exec ...
Esto busca de forma recursiva todos los archivos .py, y para cada archivo imprime el nombre de archivo y fgrep para 'hola' en ese archivo (para cada). La salida se ve así (solo ejecuté una hoy):
fuente
find . -name "*.py" -exec fgrep -l hello {} \;
- imprimirá los nombres de los archivos que coinciden, y nada más