Probieren Sie dieses Sed-Skript aus: Es ist sehr hackig und beruht auf zwei Dingen: Text enthält kein Symbol '|' und nur die letzte Zeile beginnt mit 'http:'.
:again ${ s/\n/|/g # to include first part too s/^/|/ :next # modify last non processed part s/\(.*\)|\([^|]\+\)|\(.*\)\(http:.*\)/\1|\4\/\2\n\3\4/ t next # remove unneeded guard s/^|// # remove prefix s/\(.*\n\)\([^\n]\+\)/\1/ b end } N b again :end
Wie funktioniert es?
Angenommen, wir haben diese Eingabe:
aaa bbb http://zzz
Zunächst fasst das Skript alle Zeilen aus der Datei im internen Puffer zusammen:
:again ${ # Here internal buffer will be processed b end } N b again :end
Es ist ein sehr übliches Muster in meinen Skripten, wenn sed Text nicht zeilenweise verarbeiten kann und die Eingabe nicht sehr groß ist. Bei der ersten Zeile beginnt das Skript nicht und liest die nächste Zeile ('N') bis zum Ende in den Puffer.
Wenn es die letzte Zeile ('$') erhält, kann es weiter verarbeitet werden. Und wenn es fertig ist, hört es auf ('b end'). Man kann kein anderes Label verwenden, um das Ziel zu erreichen, nur 'b' wird auch funktionieren, aber ich bevorzuge Klarheit.
Nun ist dieser Text im internen Puffer:
aaa\nbbb\nhttp://zzz
Als nächstes werden Zeilen mit dem Symbol '|' getrennt. statt '\ n':
s/\n/|/g # to include first part too s/^/|/ |aaa|bbb|http://zzz
Dann versucht es, dieses Muster zu finden
...|text|.....http://...
und ändern Sie es zu diesem
...|http://...text\n.....http://...
Aus Gründen der Gierigkeit des verwendeten regulären Ausdrucks erfolgt die Substitution vom Ende bis zum Beginn der Zeichenfolge, wobei in jedem Schritt ein Symbol '|' gestrichen wird:
Initial state of buffer: |aaa|bbb|http://zzz After first step: |aaa|http://zzz/bbb\nhttp://zzz After second step: |http://zzz/aaa\nhttp://zzz/bbb\nhttp://zzz
Die Schleife wurde mit Hilfe des Befehls 't next' organisiert. Wenn die letzte Ersetzung erfolgreich war, springt sie zum nächsten Label.
Als nächstes entfernt es nicht mehr benötigte Wächter '|' am Zeilenanfang:
s/^|// http://zzz/aaa\nhttp://zzz/bbb\nhttp://zzz
Und letzte Zeile:
s/\(.*\n\)\([^\n]\+\)/\1/ http://zzz/aaa\nhttp://zzz/bbb
Wenn der Puffer schließlich gedruckt wird, erhalten Sie Folgendes:
http://zzz/aaa http://zzz/bbb