File1
Inhalt:
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
File2
Inhalt:
line1-file2 "25"
line2-file2 "24"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
Nach der Ausführung des Perl / Shell-Skripts sollte der File2
Inhalt wie folgt aussehen:
line1-file2 "25"
line2-file2 "24"
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
dh fügen Sie den Inhalt von File1
in File2
vor der Zeile ein, die "Pointer" enthält.
text-processing
awk
sed
perl
user1228191
quelle
quelle
Antworten:
sed
hat eine Funktion dafür und kann die Modifikation inline machen:Dadurch wird Ihre Pointer- Zeile jedoch über der Datei1 platziert. Um es unten auszudrücken: Ausgabe der Verzögerungsleitung:
quelle
-e 1x -e '2,${x;p}' -e '${x;p}'
tun ist? Ich verstehe, dass Sie Sachen im Musterpuffer austauschen und dann drucken, aber ich weiß nicht, warum Sie-n
am Anfang die Option "Leise" hinzugefügt haben .Ohne zu benutzen
sed
oderawk
...Finden Sie zuerst die Linie, auf der sich Ihr Muster befindet:
Verwenden Sie dann 3 Befehle, um das gewünschte Ergebnis auszugeben:
Dies hat den Nachteil , den Zugriff auf 3 Mal der Datei
file2
, könnte aber ein klarer sein alssed
dieawk
Lösung.quelle
awk
macht das ziemlich einfach.Fügen Sie die Zeile vor der Datei ein:
Um die innere Datei nach der
Pointer
Zeile auszudrucken , ändern Sie einfach die Reihenfolge der Muster (Sie müssen ein Semikolon hinzufügen, um die Standardaktion zu erhalten), und Sie können dieline
Variable löschen:Und nur weil noch niemand benutzt
perl
hat,quelle
system("cat innerfile")
gibt dasinnerfile
an die Konsole aus. Vermisse ich etwas?Ein leichter Job für
ed
:-r file1
Liest die angegebene Datei nach der adressierten Zeile ein. In diesem Fall handelt es sich um die Zeile vor der ersten übereinstimmenden ZeilePointer
. Dadurch wird der Inhaltfile2
nur einmal eingefügt, auch wenn erPointer
in mehreren Zeilen vorkommt. Wenn Sie es vor jeder übereinstimmenden Zeile einfügen möchten, fügen Sieg
lobal flag hinzu:Ersetzen Sie
,p
durch,w
wenn Sie die Datei direkt bearbeiten möchten.Das akzeptierte
sed
Antwort funktioniert in den meisten Fällen, aber wenn sich der Marker in der letzten Zeile befindet, funktioniert der Befehl nicht wie erwartet: Er fügt den InhaltFile1
nach dem Marker ein.Ich habe es anfangs versucht mit:
das funktioniert auch gut (wie
r
es auch am Ende des Zyklus ), hat aber das gleiche Problem, wenn sich der Marker in der letzten Zeile befindet (es gibt keineN
ext-Zeile nach der letzten Zeile). Um dies zu umgehen, können Sie Ihrer Eingabe eine neue Zeile hinzufügen:Dadurch wird
file2
vor jeder übereinstimmenden Zeile Inhalt eingefügt. Um es nur vor der ersten übereinstimmenden Zeile einzufügen, können Sie einl
oop verwenden und einfach dien
ext-Zeile hineinziehen, bis Sie am Ende der Datei angelangt sind:Mit diesen
sed
Lösungen können Sie nicht mehr direkt bearbeitet werden (Sie können jedoch zu einer anderen Datei umleiten).quelle
Verwenden Sie eine Schleife, um die Zeilen in Datei2 zu lesen. Wenn Sie eine Zeile finden, die mit beginnt
Pointer
, drucken Sie file1 aus. Dies ist unten gezeigt:quelle
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:... 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 derr
ead Befehl Zeilennummer angewandt wird.Sie können es umgehen:
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 undsed
sier
in der Reihenfolge anwendet, in der sie geschrieben wurden. Es ist jedoch ein bisschen komplizierter - es bedeutet, dass man eins verwendetsed
,a
um dasPointer
Match an die Ausgabe eines anderensed
in seinem Skript anzuhängen .Der erste
sed
schreibt also im Grunde den zweitensed
ein Skript, das der zweitesed
auf Standardeingabe liest (vielleicht ...) und der Reihe nach anwendet. Der erstesed
funktioniert nur bei der ersten Übereinstimmung fürPointer
gefunden, und danachq
wird die Eingabe beendet. Seine Aufgabe ist es, ...s/[]^$&\./*[]/\\&/g;H
sed
jedes Bit, das sie liest, wörtlich interpretieren muss, um es richtig zu machen. Sobald dies erledigt ist, legen Sie eine Kopie in denH
alten Raum.s|.*|/&/!p;//!d|p; x
sed
, er sollp
jede Eingabezeile drucken,!
außer der, die/&/
wir nur mit einem Mustersafe versehen haben. und dannd
alle gleich zu eletieren.p
Drucken Sie die Befehle in der zweiten Zeilesed
, undx
ändern Sie dann denh
alten und den Musterpuffer, um mit unserer gespeicherten Kopie zu arbeiten.s|.|r file1&a\\&|p;q
\n
Zeichen, mit dem wir hier arbeiten, ist eine ewline, dased
eine vorangestellt wurde, als wirH
die Zeile zuvor bearbeitet haben . Also fügen wir den Befehl einr file1
und folgen ihm mit unserer\n
ewline, dann dem Befehla\\
füra
ppend, gefolgt von einer\n
ewline. Der Rest unsererH
eld-Linie folgt dieser letzten\n
ewline.Das Skript, das der erste schreibt, sieht ungefähr so aus:
Grundsätzlich ist die zweite
sed
wird jede Zeile drucken , sondern derjenige , der die erstensed
Sätze es ana
PPEND. Für diese bestimmte Zeile sind zwei verzögerte Schreibvorgänge für die Standardausgabe geplant - der erste ist derr
ead vonfile1
und der zweite ist eine Kopie der Zeile, die wir danach haben möchten. Diesed
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.
quelle
Mit AWK ist das ziemlich einfach:
Datei1 in Datei2 vor Muster = "Zeiger"
Laden Sie zuerst den Inhalt von File1 in eine Variable
dann machen Sie die Einfügung
(Oder wenn Sie File1 nach "Pointer" einfügen möchten)
quelle
mein bevorzugter weg: templating .
Dadurch wird jedes CHANGEME- Vorkommen in origfile durch den Inhalt von file2insert ersetzt . Entfernen Sie das letzte g von sed, um nur das erste Auftreten von CHANGEME zu ersetzen .
quelle
$x
in Ihrem ersten Befehl verwenden, wenn er nur in Ihrem zweiten Befehl definiert ist?[Dateiinhalt in eine andere Datei einfügen, BEVOR Muster]
[Nach Muster]
quelle
N
funktioniert gut, aber nicht, wenn das MUSTER mit der letzten Eingabezeile übereinstimmtquelle