GNU/Linux >> Linux Esercitazione >  >> Linux

Limitare l'uscita di ricerca ed evitare il segnale 13?

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?
Linux
  1. Output su Stdout e allo stesso tempo Grep in un file?

  2. Trova il modello e spostati?

  3. Utilizzare Command Grep e individuare?

  4. Iptables e proxy trasparenti?

  5. Grep e coda -f?

Come trovare una stringa o una parola specifica in file e directory

Confuso su Grep e il * jolly?

Usa grep per trovare il contenuto nei file e spostarli se corrispondono

Utilizzo di grep e sed per trovare e sostituire una stringa

Come combinare find e grep per una ricerca complessa? ( GNU/linux, trova, grep )

Ubuntu grep, find etc:Autorizzazione negata e Nessun output di tale file o directory