2012-12-30 2 views
155

Sto cercando una directory in modo ricorsivo utilizzando grep con i seguenti argomenti sperando di restituire solo la prima corrispondenza. Sfortunatamente, ritorna più di uno - in effetti due l'ultima volta che ho guardato. Sembra che abbia troppi argomenti, soprattutto senza ottenere il risultato desiderato. : -/Grep solo la prima corrispondenza e stop

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory 

rendimenti:

Pulsanti Operietur 
Pulsanti Operietur 

Forse grep non è il modo migliore per farlo? Dimmi, grazie mille.

risposta

262

-m 1 significa restituire la prima corrispondenza in un dato file. Ma continuerà comunque a cercare in altri file. Inoltre, se ci sono due o più abbinati nella stessa linea, tutti verranno visualizzati.

È possibile utilizzare head -1 per risolvere questo problema:

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1 
+0

fantastico! grazie. btw - ci sono tutti quegli altri argomenti necessari che ho nel comando? e cosa succede se non riesco a collegarlo per caso (per ogni evenienza). –

+2

Non penso che siano necessari (eccetto '-r' ovviamente), ma non dovrebbero ferire (non userei' -a' però) – mvp

+1

Esattamente ciò di cui avevo bisogno. Il mio pattern è stato trovato due volte sulla stessa riga e 'grep -m 1' ha restituito entrambe le istanze a causa di questo. '| head -1' lo ha risolto! – harperville

12

Il grep-un-come programma di ack ha un'opzione -1 che si ferma alla prima corrispondenza trovata da nessuna parte. Supporta il -m 1 che @mvp fa riferimento anche a. L'ho messo lì perché se sto cercando un grande albero di codice sorgente per trovare qualcosa che conosco esiste in un solo file, non è necessario trovarlo e premere Ctrl-C.

+0

quindi diresti che ack è più veloce di grep?Sono davvero preoccupato anche del fattore di velocità. –

+0

ack può essere più veloce di grep, a seconda di cosa stai cercando. Si prega di notare che ack riguarda la ricerca del codice sorgente. Se stai cercando di cercare i file generali, è meno buono, almeno in ack 1.x. Vai a leggere su Ack e vedere se forse si adatta alle tue esigenze. –

+2

Utilizzo Ack da molto tempo ma di recente sono passato a [The silver searcher] (https://github.com/ggreer/the_silver_searcher) che trovo più veloce nell'ack –

4

Un singolo rivestimento, utilizzando find:

find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit 
+4

Questo sarà * molto * lento, poiché find genererà la copia di grep per ogni file trovato. 'grep -r' lavora molto più velocemente - la sua unica copia che attraversa le directory. – mvp

+0

Vero; sebbene find può essere personalizzato per operare solo su risultati filtrati, che possono quindi rendere l'operazione molto più veloce di un grep catch-all. Dipende dal contesto. –

13

È possibile reindirizzare grep risultato a head unitamente stdbuf.

nota, che, al fine di garantire l'arresto dopo la partita ennesimo, è necessario utilizzare stdbuf per assicurarsi che non lo fanno grep tampone sua uscita:

stdbuf -oL grep -rl 'pattern' * | head -n1 
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1 
stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1 

Appena head consuma 1 riga, è terminato e grep riceverà SIGPIPE perché restituisce ancora qualcosa da pipe mentre head non c'era più.

Questo presuppone che nessun nome di file contenga newline.