Die übertragbare und effizientere Möglichkeit hierfür sind Adressen. Du kannst das:
printf %s\\n cat dog pear banana cat dog |
sed -e '/cat/!{/dog/!b' -e '};cBear'
Auf diese Weise wird die aktuelle Zeile automatisch ausgedruckt , wenn die Zeile nicht die Zeichenfolge cat enthält und die Zeichenfolge dog sed
b
ranches nicht aus dem Skript entfernt wurde, und die nächste Zeile wird eingezogen, um den nächsten Zyklus zu beginnen. Es führt daher nicht den nächsten Befehl aus, der in diesem Beispiel c
die gesamte Zeile zum Lesen von Bear ändert, aber alles tun kann.
Es ist wahrscheinlich auch erwähnenswert, dass jede Anweisung, die !b
auf diesen sed
Befehl folgt , nur mit einer Zeile übereinstimmen kann , die entweder den String enthält, dog
oder cat
- so können Sie weitere Tests durchführen, ohne die Gefahr einer Übereinstimmung mit einer Zeile, die nicht übereinstimmt - was bedeutet, dass Sie jetzt Regeln anwenden können auch nur zu dem einen oder anderen.
Aber das ist der nächste. Hier ist die Ausgabe des obigen Befehls:
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
Sie können eine Nachschlagetabelle mit Rückverweisen auch portabel implementieren.
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ cat dog /;x
};G;s/^\(.*\)\n.* \1 .*/Bear/;P;d'
Die Einrichtung dieses einfachen Beispielfalls ist sehr viel aufwändiger, kann jedoch sed
langfristig zu wesentlich flexibleren Skripten führen.
In der ersten Zeile x
ändere ich Hold Space und Pattern Space und füge dann den String <space>
cat ein<space>
Dog<space>
in den Hold Space ein, bevorx
.
Von da an und in jeder folgenden Zeile G
halte ich das Leerzeichen an das Leerzeichenmuster angehängt und überprüfe dann, ob alle Zeichen vom Zeilenanfang bis zur neuen Zeile, die ich gerade am Ende hinzugefügt habe, mit einer von Leerzeichen umgebenen Zeichenfolge übereinstimmen. Wenn ja, ersetze ich die ganze Partie durch Bär und wenn nicht, wird da kein Schaden angerichtet, weil ich weiter macheP
nur bis zur ersten im Musterbereich auftretenden Zeile weiterdrucke, und d
lösche dann alles.
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
Und wenn ich "flexibel" sage, dann meine ich das auch so. Hier ersetzt es Katze durch Braunbär und Hund durch Schwarzbär :
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ 1cat Brown 2dog Black /;x
};G;s/^\(.*\)\n.* [0-9]\1 \([^ ]*\) .*/\2Bear/;P;d'
###OUTPUT###
BrownBear
BlackBear
pear
banana
BrownBear
BlackBear
Natürlich können Sie den Inhalt der Nachschlagetabelle erheblich erweitern - ich habe die Idee aus Greg Ubbens Usenet-E-Mails zu diesem Thema aufgegriffen, als er in den 90er Jahren beschrieb, wie er aus einer einzigen sed s///
Anweisung einen groben Taschenrechner konstruierte .
-r
Option als Synonym-E
für Kompatibilität mit GNU sed. OpenBSDs und OS Xssed -E
interpretieren die Escape-Pipe als Literal-Pipe und nicht als Alternationsoperator. Hier ist ein funktionierender Link zur NetBSD-Manpage und hier einer für OpenBSD, der nicht zehn Jahre alt ist.