Es mejor explicar con ejemplos.
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 hacerlo
find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
Responder
Si te entiendo correctamente, esto es lo que quieres hacer:
find . -name "*.py" -print0 | xargs -0 grep "something" > output.txt
Busque todos los archivos con la extensión .py
, grep
solo filas que contengan something
y guarde las filas en output.txt
. Si el archivo output.txt
existe, se truncará; de lo contrario, se creará.
Usando -exec
:
find . -name "*.py" -exec grep "something" {} \; > output.txt
Estoy incorporando Chris Downs comente aquí: el comando anterior dará como resultado que grep
se ejecute tantas veces como find
encuentre nombres de ruta que superen las pruebas dadas (solo el prueba arriba). Sin embargo, si reemplaza el \;
con un +
, se llama a grep
con varios nombres de ruta de find
(hasta un cierto límite).
Consulte la pregunta Usando punto y coma (;) vs plus ( +) con el ejecutivo en buscar para obtener más información sobre el tema.
Comentarios
Responder
Si desea guardar todas las líneas coincidentes en todos los archivos en output.txt
, su último comando funciona, excepto que «le falta el ;
al final del comando.
find . -name "*.py" -type f -exec grep "something" {} \; > output.txt
Si desea que cada ejecución de grep
produzca salida a un archivo diferente, ejecute un shell para calcular el nombre del archivo de salida y realice la redirección.
find . -name "*.py" -type f -exec sh -c "grep "something" <"$0" >"$0.txt"" {} \;
Comentarios
- el último realmente bueno: D
- Para expandir la respuesta de @gilles para que sea un poco más informativa, especialmente si la lista de archivos ' re es grande, puede informar el nombre de archivo (ruta relativa) de cada archivo junto con los resultados de grep ' ed usando esto:
find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt
Y si ' quieres ver e los números de línea de las líneas grep ' ed, por supuesto, puede usargrep -n "something"
Respuesta
Para el registro, grep
tiene --include
y --exclude
argumentos que puede utilizar para filtrar los archivos que busca:
grep -r --include="*.py" "something" > output.txt
Comentarios
- Al menos GNU
grep
lo hace.
Responder
Utilice tee
:
find . -name "*.py" | tee output.txt | xargs grep "something"
La advertencia es si tiene archivos con caracteres especiales (incluidos los espacios) que xargs
y grep
no funcionarán bien con (a file.txt
se interpretará como dos archivos, a
y file.txt
). La alternativa es usar -x
o -print0
, pero cualquiera de ellos contaminará tu output.txt
. -x
usará \
para escapar de ciertos caracteres especiales y esto estará en output.txt
.-print0
usará un byte nulo como separador de campo (que también requiere xargs -0
) y output.txt
se verá como una línea de texto larga y contigua.
Cómo lidiar (o no) con esto depende de usted.
Respuesta
grep -n CThread "`find . -name "*.cpp"`"
+
en lugar de\;
, mejorará significativamente el tiempo de ejecución (ya que contaminará los argumentos antes de la ejecución hastaARG_MAX
).grep -H
si desea incluir el nombre de archivo del archivo en la salida.LC_ALL=C
justo antes dexargs
para obtener mucha velocidad adicional. Y puede usar un indicador-P6
enxargs
para que se ejecute en paralelo con (en este caso) 6 procesos (no dude en cambiar el número de 6 a algo más alto o más bajo, para ver qué ' es más rápido en su máquina y en su búsqueda). Referencia: unix.stackexchange.com/questions/131535/…+
en lugar de\;
pasará varios archivos a grep, y si algún archivo de ese conjunto contiene el texto ' algo ', todos esos archivos pasarán la prueba. Así que ganó ' t hacer lo que quieres.