GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ausgang begrenzen und Signal 13 vermeiden?

Ich habe ein Verzeichnis mit ~1M Dateien und muss nach bestimmten Mustern suchen. Ich weiß, wie man es für alle Dateien macht:

find /path/ -exec grep -H -m 1 'pattern' {} ;

Die volle Leistung ist nicht erwünscht (zu langsam). Mehrere erste Treffer sind in Ordnung, also habe ich versucht, die Anzahl der Zeilen zu begrenzen:

find /path/ -exec grep -H -m 1 'pattern' {} ; | head -n 5

Dies ergibt 5 Zeilen gefolgt von

find: `grep' terminated by signal 13

und find arbeitet weiter. Das ist hier gut erklärt. Ich habe versucht quit Aktion:

find /path/ -exec grep -H -m 1 'pattern' {} ; -quit

Dies gibt nur die erste Übereinstimmung aus.

Ist es möglich, die Ausgabe von find auf eine bestimmte Anzahl von Ergebnissen zu begrenzen (wie das Bereitstellen eines Arguments zum quit ähnlich wie head -n )?

Akzeptierte Antwort:

Da Sie bereits GNU-Erweiterungen verwenden (-quit , -H , -m1 ), können Sie genauso gut GNU grep verwenden 's -r Option, zusammen mit --line-buffered Daher gibt es die Übereinstimmungen aus, sobald sie gefunden werden, sodass es wahrscheinlicher ist, dass es von einem SIGPIPE getötet wird, sobald es die 6. Zeile schreibt:

grep -rHm1 --line-buffered pattern /path | head -n 5

Mit find , müssten Sie wahrscheinlich so etwas tun:

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

Das heißt, umschließen Sie grep in sh (Sie möchten immer noch so wenige grep ausführen Aufrufe wie möglich, daher der {} + ) und haben sh töte seinen Elternteil (find ), wenn grep stirbt an einem SIGPIPE.

Ein anderer Ansatz könnte darin bestehen, xargs zu verwenden als Alternative zu -exec {} + . xargs wird sofort beendet, wenn ein Befehl, den es erzeugt, durch ein Signal stirbt, also in:

 find . -type f -print0 |
   xargs -r0 grep -Hm1 --line-buffered pattern |
   head -n 5

(-r und -0 GNU-Erweiterungen sind). Sobald grep schreibt in die kaputte Pipe, beides grep und xargs wird beendet und find wird sich auch selbst beenden, wenn es das nächste Mal etwas danach druckt. Ausführen von find unter stdbuf -oL könnte es früher passieren lassen.

Eine POSIX-Version könnte sein:

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

Sehr ineffizient, da es mehrere Befehle für jede Datei ausführt.

Verwandte:Ubuntu – Wie sperrt man die Lüftergeschwindigkeit für AMD-GPU in Ubuntu 20.04?
Linux
  1. Ausgabe nach Stdout und gleichzeitig Grep in eine Datei?

  2. Befehl Grep und Locate verwenden?

  3. Iptables und transparente Proxys?

  4. Grep und Schwanz -f?

  5. Verwenden Sie grep, um Inhalte in Dateien zu finden und sie zu verschieben, wenn sie übereinstimmen

So finden Sie eine bestimmte Zeichenfolge oder ein bestimmtes Wort in Dateien und Verzeichnissen

Verwirrt über Grep und den Platzhalter *?

Suchen und kopieren Sie Dateien

Suchen Sie ein Verzeichnis und benennen Sie es um

Ubuntu grep, find etc:Permission denied und No such file or directory output

So grep ps-Ausgabe mit Headern