Meglio spiegare con esempi.
Posso:
find . -name "*.py" -type f > output.txt
Ma come posso memorizzare loutput nello stesso file per:
find . -name "*.py" -type f -exec grep "something" {} \
Non posso “semplicemente fare
find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
Risposta
Se ti ho capito bene, questo è quello che vuoi fare:
find . -name "*.py" -print0 | xargs -0 grep "something" > output.txt
Trova tutti i file con estensione .py
, grep
solo righe che contengono something
e salva le righe in output.txt
. Se il file output.txt
esiste, verrà troncato, altrimenti verrà creato.
Utilizzando -exec
:
find . -name "*.py" -exec grep "something" {} \; > output.txt
Sto incorporando Chris Downs commenta qui: il comando precedente risulterà in grep
eseguito tante volte quante find
trova nomi di percorso che superano i test forniti (solo il singolo test sopra). Tuttavia, se sostituisci \;
con +
, grep
viene chiamato con più nomi di percorso da find
(fino a un certo limite).
Vedi la domanda Uso del punto e virgola (;) rispetto a più ( +) con exec in find per ulteriori informazioni sullargomento.
Commenti
Risposta
Se desideri salvare tutte le righe corrispondenti in tutti i file in output.txt
, il tuo ultimo comando funziona, tranne per il fatto che “ti manca il ;
alla fine del comando.
find . -name "*.py" -type f -exec grep "something" {} \; > output.txt
Se desideri che ogni esecuzione di grep
produca output in un file diverso, eseguire una shell per calcolare il nome del file di output ed eseguire il reindirizzamento.
find . -name "*.py" -type f -exec sh -c "grep "something" <"$0" >"$0.txt"" {} \;
Commenti
- lultimo davvero carino: D
- Espandere la risposta di @gilles per renderla un po più informativa, soprattutto se lelenco dei file ' che si occupa di è grande, puoi segnalare il nome del file (percorso relativo) di ogni file insieme ai ' ed risultati utilizzando questo:
find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt
E se ' desideri vedere e i numeri di riga delle righe grep ' ed è possibile, ovviamente, utilizzaregrep -n "something"
Risposta
Per la cronaca, grep
ha --include
e --exclude
argomenti che puoi utilizzare per filtrare i file che cerca:
grep -r --include="*.py" "something" > output.txt
Commenti
- Almeno GNU
grep
lo fa.
Answer
Utilizza tee
:
find . -name "*.py" | tee output.txt | xargs grep "something"
Lavvertenza è se hai dei file con caratteri speciali (spazi inclusi) con cui xargs
e grep
non funzioneranno bene (a file.txt
verrà interpretato come due file, a
e file.txt
). Lalternativa è utilizzare -x
o -print0
, ma entrambi inquineranno il tuo output.txt
. -x
utilizzerà \
per eseguire lescape di alcuni caratteri speciali e sarà in output.txt
.-print0
utilizzerà un byte nullo come separatore di campo (che richiede anche xargs -0
) e output.txt
apparirà come una lunga riga di testo contigua.
Come gestisci (o non “t”) con questo dipende da te.
Rispondi
grep -n CThread "`find . -name "*.cpp"`"
+
invece di\;
, migliorerà notevolmente il tempo di esecuzione (poiché contatenerà gli argomenti prima dellesecuzione fino alARG_MAX
).grep -H
se desideri includere il nome del file nelloutput.LC_ALL=C
subito prima dixargs
per ottenere molta velocità extra. Inoltre, puoi utilizzare un flag-P6
suxargs
per eseguire in parallelo (in questo caso) 6 processi (non esitare a cambiare il numero da 6 a qualcosa di più alto o più basso, per vedere cosa ' è più veloce sulla tua macchina e nella tua ricerca). Riferimento: unix.stackexchange.com/questions/131535/…+
invece di\;
passerà più file a grep e se qualsiasi file in quel set contiene il testo ' qualcosa ', tutti quei file supereranno il test. Quindi ' non farà quello che vuoi.