In meinem Heirloom ed sieht das so aus:
Code: Alles auswählen
:-Q ed /tmp/a
257
/aaa/,/bbb/s/xxx/yyy/g
?
a
foo
.
w
261
q
:-Q echo $?
0
:-Q tail -1 /tmp/a
foo
:-Q
Also alles genau so wie man es erwartet ... aber die Geschichte geht noch weiter ...
k2 hat geschrieben: 10.01.2019 23:19:19
Ist nicht ganz so tragisch, denn wenn ed nichts ersetzen muss - dann kann er sich auch beenden.
Ich wuerde sagen, dass ich das anders sehe, denn wenn ich ed interaktiv nutze, wofuer ed ursprunglich ja auch da war -- er war *der* Editor in Unix, der mit dem ganz Unix geschrieben worden ist -- dann soll der sich keinesfalls beenden, wenn er wegen irgendeinem Tippfehler von mir etwas nicht finden oder nicht ersetzen kann. Ein Editor darf sich nur beenden, wenn ich es ihm sage, denn sonst wuerde ich ja moeglicherweise wertvolle Arbeitsergebnisse verlieren.
Der Funktion des Scripts tut das nichts. Allerdings nicht schön und ziemlich dirty, außerdem leite ich die Ausgabe evt. noch in ein Log-File um und dann steht da bei jedem bearbeiteten Unterverzeichnis ggf. ein "?".
Vielleicht macht es ja noch KLICK. In
http://wiki.bash-hackers.org/howto/edit-ed ist der Fall so beschrieben:
Pitfalls
...
an error stops the script
...
If you want the same behaviour you can use g/foo/ to trick ed. g/foo/ will apply the command on all lines matching foo, thus the substitution will succeed and ed will not produce an error when foo is not found:
Code: Alles auswählen
#Second version will add the line with "something" even if foo is not found
ed -s file <<< $'H\n1g/foo/s/foo/bar/\na\nsomething\n.\nw'
Aber auch dieser Vorschlag mit dem führenden g/ funktioniert nicht - vermutlich weil ich nicht nach foo suche um foo dann durch bar zu ersetzen, sondern in dem Bereich "foo1 bis foo2" "bar1" durch "bar2" ersetzen will.
Dank Euch!
Edit: habe noch versucht die Ziel-Zeilen:
/<ul class="menu">/,/<\/ul><!--menu-->/
in einen Ziel-Bereich abzuändern
g/<ul class="menu">.*<\/ul><!--menu-->/
--> das Ziel wurde nicht mehr gefunden, aber das Script auch nicht abgebrochen...
Einen Zeilenbereich kann man in ed nicht in eine einzelne Regexp umwandeln, da Regexps immer zeilenweise angewendet werden. (In Perl z.B. kann der `.' auch ein Newline matchen, in ed nicht.)
Die Bereichsangabe (/.../,/.../) ist ja schon was du haben willst: Nur in diesem Bereich sollen ueberhaupt Ersetzungen passieren.
Der Knackpunkt ist der: Wenn eine Ersetzung gemacht wird, dann wird die Zeile in der ersetzt worden ist zur aktuellen Zeile. Das anschliessende `a'-Kommando fuegt dann nach der ersetzten Zeile ein. Wenn nur aber keine Ersetzung getaetigt worden ist, dann wir die aktuelle Zeile auch nicht geaendert und folglich fuegt er hinter der Zeile ein, die davor die aktuelle Zeile war. Im konkreten Fall ist es die letzte Zeile, weil das beim Starten von ed die aktuelle Zeile ist.
Im interaktiven Fall ist das alles kein Problem, da der User ja auf die erfolgreiche oder nicht erfolgte Ersetzung reagieren kann und er weiss, wo dann eigefuegt wird. (Das ist das Szenario, das ich getestet habe.) Im gescripteten Fall kann auf das Problem nicht reagiert werden. (Das ist dein Fall.) Wenn die Ersetzung nicht stattfindet, dann wird vermutlich an der falschen Stelle eingefuegt. Um das zu verhindern, bricht ed nur dann ab, wenn er gescriptet genutzt wird, war dann mein Gedanke.
Also habe ich es ausprobiert (Heirloom ed gescriptet):
Code: Alles auswählen
:-Q ed - /tmp/a <<!
> /aaa/,/bbb/s/xxx/yyy/g
> a
> bar
> .
> w
> q
> !
?
:-Q echo $?
2
:-Q tail -1 /tmp/a
Letzte Zeile des Ursprungsdatei
:-Q
... und siehe da: ed beendet sich mit einem Fehlercode und der Append fehlt.
Damit ist klar, was passiert! (Fuer euch auch?)
Das Problem ist, dass bei einer fehlgeschlagenen Ersetzung nicht sichergestellt ist, ob die weiteren Befehle noch das Korrekte tun. Darum bricht ed da ab.
Die Frage waere also an dich, was genau du nun tatsaechlich haben willst. In welchen Faellen soll der Append wo in der Datei passieren?