¿Cómo puedo obtener los resultados de ENCONTRAR usando -EXEC y aún enviar a un archivo?


64

Mejor explicar en ejemplos.

Yo puedo:

find . -name "*.py" -type f > output.txt

Pero, ¿cómo puedo almacenar la salida en el mismo archivo para:

find . -name "*.py" -type f -exec grep "something" {} \

No puedo simplemente hacer

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt

Respuestas:


106

Si te entiendo correctamente, esto es lo que quieres hacer:

find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt

Findtodos los archivos con extensión py, grepsolo las filas que contienen somethingy guardan las filas output.txt. Si el archivo contiene algo, será reemplazado.

Editar: Usando -exec:

find . -name '*.py' -exec grep 'something' {} \; > output.txt

Estoy incorporando el comentario de Chris Downs aquí. El comando anterior dará como resultado que grepse ejecute tantas veces como findencuentre ocurrencias. Sin embargo, si reemplaza el ;con a +, grepse llama con la salida de findconcatenado (hasta cierto límite). Vea la pregunta Usando punto y coma (;) vs plus (+) con exec en find para más información sobre el tema.


16
Usar en +lugar de \;mejorará significativamente el tiempo de ejecución (ya que contaminará los argumentos antes de la ejecución hasta ARG_MAX).
Chris Down

¡Ahora entiendo el poder de los xargs! ¡Gracias!
domih

55
Úselo grep -Hsi desea incluir el nombre de archivo del archivo en la salida.
Steinar

18

Si desea guardar todas las líneas coincidentes en todos los archivos output.txt, su último comando funciona, excepto que le falta el requerido ;al final del comando.

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt

Si desea que cada ejecución de grepproduzca resultados en un archivo diferente, ejecute un shell para calcular el nombre del archivo de resultados y realizar la redirección.

find . -name "*.py" -type f -exec sh -c 'grep "something" <"$0" >"$0.txt"' {} \;

el último realmente agradable: D
bakytn

Para ampliar la respuesta de @gilles para que sea un poco más informativo, especialmente si la lista de archivos con los que está tratando es grande, puede informar el nombre del archivo (ruta relativa) de cada archivo junto con los resultados grep'ed usando esto : find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt Y si desea ver los números de línea de las líneas grep'ed que puede, por supuesto, usargrep -n "something"
JJMpls

9

Para el registro, grephas --includey --excludeargumentos que puedes usar para filtrar los archivos que busca:

grep -r --include="*.py" "something" > output.txt

2
Al menos GNU lo grephace.
phk

2

Uso tee:

find . -name '*.py' | tee output.txt | xargs grep 'something'

La advertencia, es si tiene algún archivo con caracteres especiales (incluyendo espacios) que xargsy grepno va a funcionar bien con ( a file.txtserá interpretado como dos archivos, ay file.txt). La alternativa a eso es usar el -xo -print0, pero cualquiera de ellos contaminará su output.txt. Se -xutilizará \para escapar de ciertos caracteres especiales y esto estará en output.txt. La -print0utilizará un byte nulo como separador de campos (que también requiere xargs -0) y output.txtse verá como una larga fila contigua de texto.

La forma en que trates (o no) con esto depende de ti.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.