Come posso greppare i risultati di FIND usando -EXEC e continuare a produrre file?


64

Meglio spiegare su esempi.

Io posso:

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

Ma come posso salvare l'output nello stesso file per:

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

Non posso proprio farlo

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

Risposte:


106

Se ti capisco correttamente, questo è quello che vuoi fare:

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

Findtutti i file con estensione py, grepsolo le righe che contengono somethinge salvano le righe output.txt. Se il file contiene qualcosa, verrà sostituito.

Modifica: utilizzando -exec:

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

Sto incorporando il commento di Chris Downs qui. Il comando sopra riportato verrà grepeseguito tutte le volte che findtrova occorrenze. Tuttavia, se si sostituisce ;con a +, grepviene chiamato con l'output da findconcatenato (fino a un certo limite). Vedi domanda Uso del punto e virgola (;) vs plus (+) con exec in find per ulteriori informazioni sull'argomento.


16
Utilizzare +invece di \;, migliorerà significativamente i tempi di esecuzione (poiché contatterà gli argomenti prima dell'esecuzione fino al ARG_MAX).
Chris Down,

Ora capisco il potere di xargs! Grazie!
domih,

5
Utilizzare grep -Hse si desidera includere il nome file del file nell'output.
Steinar,

18

Se si desidera salvare tutte le righe corrispondenti in tutti i file output.txt, l'ultimo comando funziona, tranne per il fatto che ;alla fine del comando manca il necessario .

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

Se si desidera che ogni esecuzione di grepproduca l'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"' {} \;

l'ultimo davvero carino: D
bakytn

Per espandere la risposta di @gilles per renderlo un po 'più informativo, specialmente se l'elenco dei file con cui hai a che fare è grande, puoi segnalare il nome del file (percorso relativo) di ciascun file insieme ai risultati grep usando questo : find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt E se vuoi vedere i numeri di riga delle linee grep che puoi, ovviamente, usaregrep -n "something"
JJMpls

9

Per la cronaca, grepha --includee --excludeargomenti che puoi usare per filtrare i file che cerca:

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

2
Almeno GNU lo grepfa.
phk,

2

Utilizzare tee:

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

L'avvertimento, è se si dispone di tutti i file con caratteri speciali (spazi inclusi), che xargse grepnon funziona bene con ( a file.txtsarà interpretato come due file, ae file.txt). L'alternativa a quella è usare il -xo -print0, ma uno di questi inquinerà il tuo output.txt. Lo -xuseranno \per sfuggire a determinati personaggi speciali e questo sarà dentro output.txt. Il -print0utilizzerà un byte null come separatore di campo (che richiede anche xargs -0) e output.txtsarà simile a una lunga linea contigua di testo.

Il modo in cui gestisci (o no) questo dipende da te.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.