Hierfür gibt es einige Möglichkeiten sed. Eine Möglichkeit ist ein verzögertes Lesen, wie es in der akzeptierten Antwort empfohlen wird. Es könnte auch so geschrieben werden:
sed -e '$!N;P;/\nPointer/r file1' -e D file2
... mit einem kleinen expliziten Look-Ahead anstelle des Look-Behind, der an anderer Stelle mit dem Haltepuffer implementiert wurde. Das wird unvermeidlich dasselbe Problem mit der letzten Zeile haben, die @don_crissti notiert, weil N das so ist Erhöhung den Leitungszyklus und der read Befehl Zeilennummer angewandt wird.
Sie können es umgehen:
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
Nicht alle seds interpretieren die -Standardeingabe, aber viele tun dies. ( POSIX sagt, sed sollte -Standard-In bedeuten, wenn der Implementierer dies wünscht- Standard-In meinen ???)
Eine andere Möglichkeit besteht darin, den angehängten Inhalt in der richtigen Reihenfolge zu verarbeiten. Es gibt einen weiteren Befehl, der die Ausgabe auf die gleiche Weise rplant wie ead und sedsie rin der Reihenfolge anwendet, in der sie geschrieben wurden. Es ist jedoch ein bisschen komplizierter - es bedeutet, dass man eins verwendet sed, aum das PointerMatch an die Ausgabe eines anderen sedin seinem Skript anzuhängen .
sed ' /Pointer/!d #only operate on first match
s/[]^$&\./*[]/\\&/g;H #escape all metachars, Hold
s|.*|/&/!p;//!d|p;g #print commands, exchange
s|.|r file1&a\\&|;q' file2| #more commands, quit
sed -nf - file2 #same input file
Der erste sedschreibt also im Grunde den zweiten sedein Skript, das der zweite sedauf Standardeingabe liest (vielleicht ...) und der Reihe nach anwendet. Der erste sedfunktioniert nur bei der ersten Übereinstimmung für Pointergefunden, und danach qwird die Eingabe beendet. Seine Aufgabe ist es, ...
s/[]^$&\./*[]/\\&/g;H
- Stellen Sie sicher, dass alle Musterzeichen sicher mit Backslash versehen sind, da die Sekunde
sedjedes Bit, das sie liest, wörtlich interpretieren muss, um es richtig zu machen. Sobald dies erledigt ist, legen Sie eine Kopie in den Halten Raum.
s|.*|/&/!p;//!d|p; x
- Sagen Sie dem Zweiten
sed, er soll pjede Eingabezeile drucken, !außer der, die /&/wir nur mit einem Mustersafe versehen haben. und dann dalle gleich zu eletieren. pDrucken Sie die Befehle in der zweiten Zeile sed, und xändern Sie dann den halten und den Musterpuffer, um mit unserer gespeicherten Kopie zu arbeiten.
s|.|r file1&a\\&|p;q
- Das einzige
\nZeichen, mit dem wir hier arbeiten, ist eine ewline, da sedeine vorangestellt wurde, als wir Hdie Zeile zuvor bearbeitet haben . Also fügen wir den Befehl ein r file1und folgen ihm mit unserer \newline, dann dem Befehl a\\für append, gefolgt von einer \newline. Der Rest unserer Held-Linie folgt dieser letzten \newline.
Das Skript, das der erste schreibt, sieht ungefähr so aus:
/Pointer-file2 "23"/!p;//!d
r file1
a\
Pointer-file2 "23"
Grundsätzlich ist die zweite sedwird jede Zeile drucken , sondern derjenige , der die ersten sedSätze es an aPPEND. Für diese bestimmte Zeile sind zwei verzögerte Schreibvorgänge für die Standardausgabe geplant - der erste ist der read von file1und der zweite ist eine Kopie der Zeile, die wir danach haben möchten. Die sedErstbehandlung ist in diesem Fall gar nicht nötig (siehe? Keine Backslashes), aber es ist wichtig, sicher zu fliehen, wie ich es hier tue, wenn eine Musterübereinstimmung als Eingabe verwendet wird.
Wie auch immer, es gibt ein paar Möglichkeiten.