Ersetzen Sie das erste Auftreten eines Musters in einer Zeile durch alle Zeilen in einer Datei mit sed

16

Ist es möglich, es in einem Liner zu tun?

Ich habe eine Ausgabe wie diese:

"First line" - Description  
" Second line" - Description  
"Third line" - Description  
" Fourth line" - Description  

Diese Eingabe wird automatisch generiert.

Ich möchte das erste Vorkommen von "(Anführungszeichen + Leerzeichen) durch "(Anführungszeichen) für jede Zeile ersetzen . Wenn ich die Substitution global anwende, ändert sich auch jedes Vorkommen von line" -bis line"-. Daher habe ich mich gefragt, ob es möglich ist, einen sed one-Liner zu verwenden, um dies zu erreichen.

Ich habe versucht, ^so zu verwenden

sed -r ':a;N;$!ba;s/(\^\" )/\"/g'

Aber es funktioniert nicht, es ersetzt nichts. Ich habe es versucht

sed -r ':a;N;$!ba;s/(^|\" )/\"/g'

und es ersetzt alle Vorkommen. Ich habe gerade angefangen, sed zu verwenden, daher weiß ich nicht wirklich, ob ich etwas falsch mache.

Was fehlt mir hier?

Steve B.
quelle
Ein Hinweis zu Beschriftungen: Der Befehl, den Sie oben geschrieben haben, funktioniert möglicherweise in einigen Implementierungen von sed, aber um die Portabilität zu gewährleisten und wirklich seltsame Fehler zu vermeiden, sollten Sie ein bestimmtes Befehlsargument nach einer Beschriftung beenden (falls Sie sie überhaupt benötigen). ZBsed -e ':a' -e 'N;$!ba' -e 'whatever'
Wildcard

Antworten:

33

Du überdenkst es. sedErsetzt standardmäßig nur die erste Instanz in einer Zeile (ohne den /gModifikator), obwohl Sie immer noch verankern möchten, weil Sie nicht so sehr die erste Instanz in der Zeile als die am Anfang der Zeile möchten. und normalerweise benötigen Sie nicht die expliziten Zeilenaktionen, die Sie verwenden möchten (warum?).

sed 's/^" /"/'
Geekosaurier
quelle
Vielen Dank! Ich dachte, es sei notwendig, die Zeilenaktionen bei der Arbeit an einer Datei explizit zu deklarieren, darüber zu lesen und sie einfach weiter zu verwenden. Ich habe es wirklich überlegt, das könnte nicht einfacher sein und es macht den Trick :)
Steve B.
Ich bin versucht zu sagen, dass diese Befehle ziemlich veraltet sind. Es ist möglich, ziemlich komplexe mehrzeilige Dinge mit ihnen zu tun, aber es ist nicht einfach , dies zu tun, und heutzutage ist es wirklich besser, stattdessen Perl / Python / Ruby / was auch immer zu verwenden.
Geekosaurier
Stimme dem obigen Kommentar überhaupt nicht zu; Mehrzeilige sedBefehle wie Nund Beschriftungen wie :asind überhaupt nicht veraltet und sie sind portabel und POSIX-spezifiziert , im Gegensatz zu Perl / Python / Ruby / was auch immer. Es ist jedoch wahr, dass Sie lernen sollten , wenn Sie feststellen, dass Sie sie häufig brauchen . awk
Wildcard
2

Eine allgemeinere Antwort, da ich die Antwort von Geekosaur nicht kommentieren kann - Sie würden das ^ (Ankeranfang) nicht setzen. Wenn Sie beispielsweise das erste Vorkommen von A durch B ersetzen möchten, haben Sie

sed 's/A/B/'
Spektrum
quelle