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

Wie kehrt der Befehl Sed ‘1!g;h;$!d’ den Inhalt einer Datei um?

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 das G Befehl wird in jeder Zeile außer der ersten ausgeführt (der ! negiert die 1 ). 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).

  1. Nun, wenn die erste Zeile gelesen wird, sed führt das h 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.
  2. 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 das h 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.
  3. Schritt 2 ist nun mit allen Linien erledigt. Wir springen zur letzten Zeile.
  4. 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 .
Verwandte:Eine Binärdatei mit dd patchen?
Linux
  1. So extrahieren Sie die tar.gz-Datei in Linux mithilfe der Befehlszeile

  2. Wie fügt man Text vor der ersten Zeile einer Datei ein?

  3. Wie funktioniert der Tee-Befehl?

  4. Woher weiß der Befehl Xdg-open, welche Anwendung zum Öffnen einer Datei verwendet werden soll?

  5. Wie kann ich von der Befehlszeile aus mounten, wie es Nautilus tut?

Zeigen Sie den Inhalt einer Datei in der Linux-Befehlszeile an

So entfernen Sie Zeilen aus einer Datei mit dem Sed-Befehl

Schneller Unix-Befehl zum Anzeigen bestimmter Zeilen in der Mitte einer Datei?

Der Linux-Befehl sed ändert die Zieldatei nicht

Wie erhalte ich die URL der Dropbox-Datei von der Befehlszeile?

Wie funktioniert der ps-Befehl?