Come eseguire find -exec?


Risposte:


710

Hai perso un ;(scappato qui \;per impedire alla shell di interpretarlo) o un +e un {}:

find . -exec grep chrome {} \;

o

find . -exec grep chrome {} +

findverrà eseguito grepe sostituirà {}con i nomi di file trovati. La differenza tra ;e +è che con ;un singolo grepcomando per ogni file viene eseguito mentre con il +maggior numero possibile di file vengono dati come parametri grepcontemporaneamente.


30
Se usi \; Il costrutto finale grep viene passato un file alla volta, quindi non visualizza il nome del file per impostazione predefinita, ma solo le righe corrispondenti. Per ottenere un elenco di file invece aggiungi l'uso grep -lsall'interno del costrutto find.
Caleb,

9
find . -exec grep foo {} +ti mostrerà l'output in questo modo./dir/file.py:from foo import bar
sg

10
find . -exec grep foo {} \;ti mostrerà l'output in questo modofrom foo import bar
sg

9
find . -exec grep -l foo {} +ti mostrerà l'output in questo modo./dir/file.py
sg

8
find . -exec grep -l foo {} \;ti mostrerà l'output in questo modo./dir/file.py
sg

46

Non è necessario utilizzare findper questo affatto; grep è in grado di gestire l'apertura dei file da un elenco glob di tutto nella directory corrente:

grep chrome *

... o anche ricorsivamente per la cartella e tutto ciò che contiene:

grep chrome . -R

22
grep si strozzerà se l'espansione supera ARG_MAX. -R visiterà tutto mentre usando find si può più facilmente aggiungere primitive per escludere determinati file (-name, ecc.) O nemmeno visitare sottotitoli (-prune).
Mel

6
Aspetti positivi @Mel. Il mio punto era che con ogni probabilità la parte che chiedeva stava rendendo le cose più complesse di quanto avrebbero dovuto essere introducendo findquando greppoteva fare il lavoro, ma in alcuni casi sarebbe più efficace usare find per affinare la lista dei file prima di uscire grep.
Caleb,

4
In greptal caso, @Mel non si strozza exec.
Chris Down,

Funziona solo nel caso in cui tutti i file si trovino nella stessa directory, non quando sono distribuiti su sottodirectory.
Yaba,

1
@Yaba La mia risposta afferma come gestire il caso dei file distribuiti su sottodirectory.
Caleb,

18
find . | xargs grep 'chrome'

puoi anche fare:

find . | xargs grep 'chrome' -ls

Il primo mostra le linee nei file, il secondo elenca solo i file.

L'opzione di Caleb è più ordinata, meno tasti.


11
Il problema xargsè che si aspetta che il suo input venga quotato in un modo peculiare che findnon produce. Quindi find … | xargs …non funziona se hai nomi di file contenenti spazi bianchi o \'".
Gilles,

3
@Gilles Puoi aggirare quel problema usando qualcosa del genere in find . | xargs -n1 -iX grep "X" 'chrome'modo che gli argomenti vengano alimentati uno alla volta e citati. Ovviamente questo è un modo orribilmente inefficiente per gestire questo esempio, ma per alcune situazioni è bello.
Caleb,

Per completezza dovremmo anche menzionare l'opzione -i per l'insensibilità ai casi con 'grep'. Inoltre c'è -iname in cerca di insensibilità al caso.
Mathew,

9
@Caleb: l'unico modo affidabile al 100% per xargsfar fronte ai nomi dei file Linux è find ... -print0 | xargs -0, usando NUL come separatore. Alternativa: xargs -d '\n'utilizzo di newline come separatore, affidabilità del 99%.
Grawity,

Lo uso spesso, ma fallirà per elenchi molto lunghi di nomi di file, a quel punto trovare -exec diventa il vincitore.
Spacemoose il


1

Per visualizzare un elenco di file anziché linee:

grep -l "chrome" *

o:

grep -r -l "chrome" .

1

Ecco un esempio di come di solito uso find / exec ...

find  . -name "*.py" -print -exec fgrep hello {} \;

Questo cerca ricorsivamente tutti i file .py e per ogni file stampa il (i) file (i) il nome del file e fgrep per 'ciao' su quel (per ciascuno) file. L'output sembra (ne ho appena eseguito uno oggi):

./r1.py
./cgi-bin/tst1.py
print "hello"
./app/__init__.py
./app/views.py
./app/flask1.py
./run.py
./tst2.py
print "hello again"

1
per non scherzare con il tuo flusso di lavoro, ma ti potrebbe piacere: find . -name "*.py" -exec fgrep -l hello {} \; - stamperà i nomi dei file che corrispondono, e nient'altro
Jeff Schaller
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.