Ho una directory con file ~ 1M e ho bisogno di cercare modelli particolari. So come farlo per tutti i file:
find /path/ -exec grep -H -m 1 'pattern' {} ;
L'uscita completa non è desiderata (troppo lenta). Diversi primi colpi sono OK, quindi ho cercato di limitare il numero di righe:
find /path/ -exec grep -H -m 1 'pattern' {} ; | head -n 5
Ciò si traduce in 5 righe seguite da
find: `grep' terminated by signal 13
e find continua a funzionare. Questo è ben spiegato qui. Ho provato a quit azione:
find /path/ -exec grep -H -m 1 'pattern' {} ; -quit
Questo restituisce solo la prima corrispondenza.
È possibile limitare l'output di ricerca con un numero specifico di risultati (come fornire un argomento per quit simile a head -n )?
Risposta accettata:
Dato che stai già utilizzando le estensioni GNU (-quit , -H , -m1 ), potresti anche usare GNU grep 's -r opzione, insieme a --line-buffered quindi emette le corrispondenze non appena vengono trovate, quindi è più probabile che venga ucciso da un SIGPIPE non appena scrive la sesta riga:
grep -rHm1 --line-buffered pattern /path | head -n 5
Con find , probabilmente dovresti fare qualcosa del tipo:
find /path -type f -exec sh -c '
grep -Hm1 --line-buffered pattern "[email protected]"
[ "$(kill -l "$?")" = PIPE ] && kill -s PIPE "$PPID"
' sh {} + | head -n 5
Cioè, avvolgi grep in sh (vuoi ancora eseguire come pochi grep invocazioni possibili, da qui il {} + ), e avere sh uccidi il suo genitore (find ) quando grep muore di un SIGPIPE.
Un altro approccio potrebbe essere quello di utilizzare xargs in alternativa a -exec {} + . xargs esce immediatamente quando un comando che genera muore di un segnale, quindi in:
find . -type f -print0 |
xargs -r0 grep -Hm1 --line-buffered pattern |
head -n 5
(-r e -0 essendo estensioni GNU). Non appena grep scrive sulla pipe rotta, entrambi grep e xargs uscirà e find uscirà anche la prossima volta che stampa qualcosa dopo. Esecuzione di find sotto stdbuf -oL potrebbe farlo accadere prima.
Una versione POSIX potrebbe essere:
trap - PIPE # restore default SIGPIPE handler in case it was disabled
RE=pattern find /path -type f -exec sh -c '
for file do
awk '''
$0 ~ ENVIRON["RE"] {
print FILENAME ": " $0
exit
}''' < "$file"
if [ "$(kill -l "$?")" = PIPE ]; then
kill -s PIPE "$PPID"
exit
fi
done' sh {} + | head -n 5
Molto inefficiente in quanto esegue diversi comandi per ogni file.
Correlati:Ubuntu - Come bloccare la velocità della ventola per AMD gpu in Ubuntu 20.04?