Meine Frage bezieht sich auf den sed
-spezifische Lösung, die in dieser Antwort für diese Frage des Reverse Grepping angegeben ist. Der sed
/grep
Lösung, die ich nicht entziffern kann, ist die folgende:
sed '1!G;h;$!d' file
Kann bitte jemand diesen Befehl entziffern?
Ich weiß aus VI(M)-Wissen, dass G die letzte Zeile der Datei bezeichnet und dass in sed ein Knall(!) gefolgt von einer Adresse ein bisschen wie grep -v
funktioniert das heißt, es wird nicht mit dieser Zeile übereinstimmen. Aber als Ganzes ist mir das obige Inline-sed-Skript ein Rätsel.
Akzeptierte Antwort:
Dies kehrt die Datei Zeile für Zeile um.
sed '1!G;h;$!d' file
Zuerst sed
hat ein Haltefeld und ein Musterraum . Wir müssen zwischen ihnen unterscheiden, bevor wir uns auf diesen speziellen Befehl konzentrieren.
Wenn sed
liest eine neue Zeile, wird sie in den Musterbereich geladen. Daher wird dieser Speicherplatz jedes Mal überschrieben, wenn eine neue Zeile verarbeitet wird. Andererseits ist der Haltebereich über die gesamte Verarbeitung konsistent und Werte können dort für eine spätere Verwendung gespeichert werden.
Zum Befehl:
Es gibt 3 Befehle in dieser Anweisung:1!G
, h
und $!d
-
1!G
bedeutet, dass dasG
Befehl wird in jeder Zeile außer der ersten ausgeführt (der!
negiert die1
).G
bedeutet anhängen was sich im Haltebereich befindet, in den Musterbereich. -
h
gilt für jede Zeile. Es kopiert den Musterbereich in den Haltebereich (und überschreibt ihn). -
$!d
gilt für jede Zeile außer der letzten ($
stellt die letzte Zeile dar,!
negiert es).d
ist der Befehl zum Löschen der Zeile (Musterraum).
- Nun, wenn die erste Zeile gelesen wird,
sed
führt dash
aus Befehl. Die erste Zeile wird in den Haltebereich kopiert. Dann wird er gelöscht, da er mit$!
übereinstimmt Zustand.sed
fährt mit der zweiten Zeile fort. - Die zweite Zeile entspricht der Bedingung
1!
(es ist nicht die erste Zeile), und so wird der Halteraum (der die erste Zeile hat) an den Musterraum (der die zweite Zeile hat) angehängt. Danach folgt im Musterbereich nun die zweite Zeile, gefolgt von der ersten Zeile, die durch einen Zeilenumbruch begrenzt ist. Jetzt dash
Befehl gilt (wie in jeder Zeile); Alles, was sich im Musterbereich befindet, wird in den Haltebereich kopiert. Die dritte Anweisung ($!d
) gilt:Die Linie wird aus dem Musterbereich gelöscht. - Schritt 2 ist nun mit allen Linien erledigt. Wir springen zur letzten Zeile.
- In der letzten Zeile (
$
) ist fast der gesamte Schritt 2 erledigt, aber nicht der Löschteil (d
).sed
, wenn es ohne-n
aufgerufen wird , druckt den Musterraum automatisch am Ende der Verarbeitung für jede Eingabezeile. Wenn er also nicht gelöscht wird, wird der Musterbereich gedruckt. Es enthält nun alle Zeilen in umgekehrter Reihenfolge .