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?