Der Grund warum
tac file | grep foo | head -n 1
hört nicht beim ersten Treffer auf, liegt an der Zwischenspeicherung.
Wird normalerweise head -n 1
nach dem Lesen einer Zeile beendet. Also grep
sollte man sich ein SIGPIPE zulegen und gleich beenden, sobald es seine zweite Zeile schreibt.
Aber was passiert ist, dass, weil seine Ausgabe nicht an ein Terminal geht, es grep
puffert. Das heißt, es wird nicht geschrieben, bis es genug akkumuliert hat (4096 Bytes in meinem Test mit GNU grep).
Das heißt, es grep
wird nicht beendet, bevor 8192 Datenbytes geschrieben wurden, also wahrscheinlich ziemlich viele Zeilen.
Mit GNU grep
können Sie das Programm schneller beenden, indem --line-buffered
Sie festlegen, dass Zeilen geschrieben werden sollen, sobald sie gefunden werden, unabhängig davon, ob sie zu einem Terminal geleitet werden oder nicht. So grep
würde dann die zweite Zeile verlassen, die es findet.
Aber mit GNU grep
kannst du es trotzdem verwenden, -m 1
wie @terdon gezeigt hat, was besser ist, wenn es beim ersten Match beendet wird.
Wenn Sie grep
nicht GNU sind grep
, können Sie stattdessen sed
oder awk
verwenden. Da tac
es sich jedoch um einen GNU-Befehl handelt, bezweifle ich, dass Sie ein System finden, bei tac
dem grep
GNU nicht verwendet wird grep
.
tac file | sed "/$pattern/!d;q" # BRE
tac file | P=$pattern awk '$0 ~ ENVIRON["P"] {print; exit}' # ERE
Einige Systeme müssen tail -r
dasselbe tun wie GNU tac
.
Beachten Sie, dass für eine regelmäßige (durchsuchbar) Dateien, tac
und tail -r
sind effizient , weil sie die Dateien rückwärts lesen tun, sind sie nicht nur die Datei vollständig im Speicher zu lesen , bevor sie rückwärts Druck (wie @ SLMs sed Ansatz oder tac
auf nicht-regulären Dateien würde) .
Auf Systemen, auf denen weder verfügbar tac
noch tail -r
verfügbar sind, besteht die einzige Möglichkeit darin, das Rückwärtslesen von Hand mit folgenden Programmiersprachen zu implementieren perl
:
grep -e "$pattern" file | tail -n1
Oder:
sed "/$pattern/h;$!d;g" file
Aber das bedeutet, alle Übereinstimmungen zu finden und nur die letzte zu drucken.