sed-Muster Leertaste und Leertaste gedrückt halten

sed-Muster Leertaste und Leertaste gedrückt halten

ich habe das gerade durchgemacht und konnte es nicht verstehen.

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\nblub/ p }' file.

wo sich die Cat-Datei befindet:

 foo
 foo
 bar

warum gibt es das 1!Hdenn für mich 1hüberschreibt den Musterraum und 1!Hist nutzlos

Aber der Sed-Einzeiler scheint gut zu funktionieren.

Antwort1

SehenAntwort von @manatworkfür den eigentlichen Grund 1h;1!H, aber ich wollte einen Hinweis zur Portabilität hinzufügen.

Die standardmäßige und portable Syntax sollte lauten:

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\
blub/p;}'

Andernfalls funktioniert es in den meisten sedImplementierungen nicht, beispielsweise in den traditionellen Unix-Implementierungen.

Das wird \nauf der linken Seite des sBefehls verstanden, aber Sie müssen auf der rechten Seite einen Backslash gefolgt von einem tatsächlichen Zeilenumbruchzeichen verwenden. Sie benötigen außerdem das ;zwischen dem sBefehl und }und kein Leerzeichen vor dem p.

Sie können den Inhalt der Datei auch im Musterbereich statt im Haltebereich speichern:

sed -n '
  :1
  $!{
   N;b1
  }
  s/foo\nbar/blah\
blup/p'

Aber sowohl beim Muster als auch beim Speicherplatz sedfunktioniert das bei den meisten Implementierungen nur mit kleinen Dateien, da die meisten Nicht-GNU-Implementierungen für diese eine begrenzte Größe haben (und POSIX nur erfordert, dass sie 8 KiB Daten speichern können).

Für den mobilen Einsatz sind folgende Methoden besser geeignet perl:

perl -0777 -ne 'print if s/foo\nbar/blah\nblup/'

Da die Größe in perloder GNU nicht begrenzt ist sed, müssen Sie sich jedoch darüber im Klaren sein, dass dies Auswirkungen auf die Leistung des Systems haben kann, da möglicherweise der gesamte Systemspeicher verwendet wird, wenn Sie keine administrativ festgelegten Grenzen für die Speichernutzung pro Prozess haben.

Antwort2

warum gibt es 1!H, weil für mich 1h den Musterraum überschreibt und 1!H keinen Nutzen hat

Es erfolgt kein Überschreiben, da sie nicht in derselben Eingabezeile ausgeführt werden:

1h   # when input line number is 1, copy pattern space to hold space
1!H  # when input line number is not 1, append pattern space to hold space

Dies ist notwendig, da info sed:

`H'
     Append a newline to the contents of the hold space, and then
     append the contents of the pattern space to that of the hold space.

Wenn Sie also nur Halle Zeilen anhängen, wird vor der ersten Zeile ein zusätzlicher Zeilenumbruch eingefügt:

bash-4.2$ seq 3 | sed -n 'H; ${g; p;}'

1
2
3
bash-4.2$ seq 3 | sed -n '1h; 1!H; ${g; p;}'
1
2
3

verwandte Informationen