
Mit sed (GNU sed) 4.2.2 möchte ich:
- Übereinstimmen
Line1
- Überprüfen Sie
Line2
direkt darunterLine1
, ob es gleich istString
- Wenn nicht, fügen Sie
String
danach anLine1
(oder davor einfügenLine2
)
Was ich versucht habe:
echo -e "Line1\nLine2\nLine3" | sed '/Line1/n;/^String$/!iString'
aber es gibt zurück:
Zeile1
Zeichenfolge
Zeile2
Zeichenfolge
Zeile3
Ich habe auch versucht:
echo -e "Line1\nLine2\nLine3" | sed '/Line1/{n;/^String$/!iString}'
aber es kehrt zurück
sed: -e Ausdruck Nr. 1, Zeichen 0: nicht übereinstimmendes `{'
Ich weiß, wie es anders geht, auch mit sed, aber ich versuche zu verstehen, wie ich es genau so erreichen kann, wie ich es oben beschrieben habe. Sagen Sie mir bitte auch, was mit meinem Code nicht stimmt.
Antwort1
Versuchen:
sed '/Line1/{N; /\nString$/b; s/\n/\nString\n/}' file
Einschränkung: Wenn zwei Zeilen Line1
hintereinander erscheinen, kann dies zu dem gewünschten Ergebnis führen, muss es aber nicht.
Beispiel
Betrachten wir diese Testdatei:
$ cat file
Line1
String
Line2
String
Line3
Line1
Line2
Und wenden wir unseren Befehl an:
$ sed '/Line1/{N; /\nString$/b; s/\n/\nString\n/}' file
Line1
String
Line2
String
Line3
Line1
String
Line2
Wie es funktioniert
Line1/{...}
Dadurch werden die Befehle in geschweiften Klammern nur ausgeführt, wenn die aktuelle Zeile mit dem regulären Ausdruck übereinstimmt
Line1
.N
Dadurch wird die nächste Zeile eingelesen und an die aktuelle Zeile angehängt, wobei die beiden Zeilen durch einen Zeilenumbruch getrennt sind.
/\nString$/b
Wenn die zweite Zeile mit dem regulären Ausdruck übereinstimmt
\nString$
, überspringen Sie den Rest des Befehls („branch“,b
).s/\n/\nString\n/
Dadurch wird der Zeilenumbruch, der die erste und die zweite Zeile trennt, durch einen Zeilenumbruch ersetzt,
String
gefolgt von einem weiteren Zeilenumbruch.