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 r
ead Befehl Zeilennummer angewandt wird.
Sie können es umgehen:
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
Nicht alle sed
s 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 r
plant wie ead und sed
sie r
in der Reihenfolge anwendet, in der sie geschrieben wurden. Es ist jedoch ein bisschen komplizierter - es bedeutet, dass man eins verwendet sed
, a
um das Pointer
Match an die Ausgabe eines anderen sed
in 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 sed
schreibt also im Grunde den zweiten sed
ein Skript, das der zweite sed
auf Standardeingabe liest (vielleicht ...) und der Reihe nach anwendet. Der erste sed
funktioniert nur bei der ersten Übereinstimmung für Pointer
gefunden, und danach q
wird die Eingabe beendet. Seine Aufgabe ist es, ...
s/[]^$&\./*[]/\\&/g;H
- Stellen Sie sicher, dass alle Musterzeichen sicher mit Backslash versehen sind, da die Sekunde
sed
jedes Bit, das sie liest, wörtlich interpretieren muss, um es richtig zu machen. Sobald dies erledigt ist, legen Sie eine Kopie in den H
alten Raum.
s|.*|/&/!p;//!d|p; x
- Sagen Sie dem Zweiten
sed
, er soll p
jede Eingabezeile drucken, !
außer der, die /&/
wir nur mit einem Mustersafe versehen haben. und dann d
alle gleich zu eletieren. p
Drucken Sie die Befehle in der zweiten Zeile sed
, und x
ändern Sie dann den h
alten und den Musterpuffer, um mit unserer gespeicherten Kopie zu arbeiten.
s|.|r file1&a\\&|p;q
- Das einzige
\n
Zeichen, mit dem wir hier arbeiten, ist eine ewline, da sed
eine vorangestellt wurde, als wir H
die Zeile zuvor bearbeitet haben . Also fügen wir den Befehl ein r file1
und folgen ihm mit unserer \n
ewline, dann dem Befehl a\\
für a
ppend, gefolgt von einer \n
ewline. Der Rest unserer H
eld-Linie folgt dieser letzten \n
ewline.
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 sed
wird jede Zeile drucken , sondern derjenige , der die ersten sed
Sätze es an a
PPEND. Für diese bestimmte Zeile sind zwei verzögerte Schreibvorgänge für die Standardausgabe geplant - der erste ist der r
ead von file1
und der zweite ist eine Kopie der Zeile, die wir danach haben möchten. Die sed
Erstbehandlung 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.