2016-08-14 1 views
2

Ich benutze a und i in sed Skripte oft, aber wie man sie in der Regel in einem Einzeiler (oder genauer gesagt, Ende des Textes zu verwenden)Sed: Mit a, c oder i in einem Einzeiler

Ich habe versucht, den Text zu zitieren, eine neue Zeile char hinzufügen, um das Ende des Textes zu bedeuten, die neue Zeile zu entkommen; Nichts funktioniert, sed behandelt einfach alle Zeichen bis zum Ende der Shell-Zeile als Text, mit dem man arbeiten kann.

Dies führt zu einem Problem, wenn Sie weitere Aktionen ausführen, da diese als Text und nicht als Befehle für sed behandelt werden, z. B. p.

Das ist in Ordnung:

/RANGE_start/,/RANGE_end/{ 
    s/foo/bar/ 
    /RANGE_end/a \--- This is the end of the range block --- 
    p 
} 

Dies funktioniert nicht gut:

/RANGE_start/,/RANGE_end/{s/foo/bar/;/RANGE_end/a \--- This is the end of the range block ---; p} 

wo der Ausgang

ist --- Dies ist das Ende des Bereichs blockieren - -; p}

oder, da ich versuche, p zu verwenden, keine Ausgabe (vorausgesetzt, sed wurde mit -n gestartet).

Gibt es ein spezielles Zeichen, das ich an a übergeben kann, c und ich, um das Ende des Textes zu bezeichnen?

(BTW, ist dies nicht nur um Einzeiler, (in einer anderen Frage, die ich fragen), ist es auch in einer Datei über das Schreiben mit w, wo der Text nicht in die Datei geschrieben bekommt.)

[Ich vermute, dass ich einige Gnu-Details oben verwende.]

+1

produziert Ihr Standard 'sed' Ausgang für' sed --version'? Bitte fügen Sie das zu Ihrem Q hinzu. Wenn nicht, UND, da Sie Ihr Q mit 'unix' getaggt haben, kann Ihr sed eine alte Version sein, die' \ a \, i \, c \ .' erfordert, um die letzten Zeichen auf dem zu sein Zeile, gefolgt von add, ins, oder ändern Sie den Text in separaten Zeilen, bis eine leere Zeile die "Eingabe" für diese Operation beendet. Ein Liner wird, IMHO, stark überbewertet. Warte, bis du den Oneliner von jemand anderem verbessern musst, wenn du etwas Code übernimmst, dann magst du sie nicht so sehr, aber ja, manchmal wegen anderer Tools-Einschränkungen brauchst du den One-Liner ;-). Viel Glück! – shellter

+1

One-Liner ist ein abwertender Ausdruck - es ist kein Ziel, um jeden Preis erreicht werden.Wenn Sie in meinem Buch die Befehle "a", "c", "i" in "sed" verwenden, verzichten Sie auf die "Einzeiler" -Optionen. Wenn Sie das Gefühl haben, dass Sie GNU 'sed' benutzen müssen und verwenden, können Sie jede 'Zeile' in ein separates '-e'-Argument setzen, wobei alle außer der letzten mit einem Backslash enden:' sed -e' 1a \ '-e' line1 \ '-e' line2-and-final'' - wenn du BSD (Mac OS X) 'sed' benutzt, funktioniert das auch nicht. Sie können das Skript 'sed' immer in eine Datei einfügen und dann 'sed -f sed.script files *' verwenden, um die Dateien mit dem Skript zu bearbeiten. –

Antwort

3

Möchten Sie foo durch einen Balken in einem Bereich ersetzen und einen Text am Ende des Bereichs drucken? Mit awk können Sie schreiben, dass Bereiche mit, wie Sie zu haben, in sed:

awk ' 
/RANGE_start/,/RANGE_end/ { 
    sub(/foo/,"bar") 
    print 
    if (/RANGE_end/) { 
     print "--- This is the end of the range block ---" 
    } 
} 
' 

aber awk können Sie auch Variablen verwenden, anstatt, so dass Sie mit den doppelten Bedingungen nicht stecken Umgang erforderlich, wenn Bereiche mit (Anmerkung RANGE_END nur einmal in der unten stehenden Skript getestet):

awk ' 
/RANGE_start/ { inRange = 1 } 
inRange { 
    sub(/foo/,"bar") 
    print 
    if (/RANGE_end/) { 
     print "--- This is the end of the range block ---" 
     inRange = 0 
    } 
} 
' 

diese Idee des Umgangs mit Bereichen gegeben, indem einen Flag verwendet, um anzuzeigen, wenn Sie im Bereich sind, dann schauen Sie, wie einfach es ist die Bereichsstartdruck/Endlinie zu wählen ist (oder irgendetwas anderes!), indem Sie einfach die Position ändern, an der die Flagge gesetzt/getestet wurde:

$ seq 1 10 | awk '/3/{f=1} f{print} /7/{f=0}' 
3 
4 
5 
6 
7 

$ seq 1 10 | awk 'f{print} /3/{f=1} /7/{f=0}' 
4 
5 
6 
7 

$ seq 1 10 | awk '/3/{f=1} /7/{f=0} f{print}' 
3 
4 
5 
6 

$ seq 1 10 | awk '/7/{f=0} f{print} /3/{f=1}' 
4 
5 
6 

sed ist ideal für einfache Ersetzungen einzelner Zeilen, aber für alles andere sollten Sie awk für Klarheit, Einfachheit, Effizienz, Portabilität und die meisten anderen wünschenswerten Softwareattribute verwenden.

+1

Vielen Dank für Ihre ausführliche Antwort, die einige Hinweise zur Verwendung von awk gab. Ich fühle mich mit sed so tendieren, eine eingebaute Neigung zu haben. Ich denke, ich habe an Awk als "Heavy Lifter" gedacht und benutze sed meistens, wenn ich denke, dass meine Lösung nur ein geringes Gewicht benötigt. In diesem Fall ist dies Teil eines längeren sed-Skripts. Das Problem ist mir aufgefallen, dass es so befremdlich ist, dass das neue Zeilen-Zeichen, das so umfassend und gründlich in sed verwendet wird, um Datensätze zu beschreiben, nicht für a, c & i gilt. Es ist fast so, als ob diese drei Befehle später von einem Dritten geschrieben worden wären, ohne Rücksicht auf die Geschichte und die Vorgehensweise von sed. –

+1

'ein langes sed-Skript' - Wörter, die niemals ausgesprochen werden sollten ;-). Ich benutze Sed seit 35 Jahren und Awk für 25. Sie sind beide großartige Werkzeuge für das, was sie am besten sind. Sie sollten wirklich mehr Zeit in die Verwendung von/awk investieren, denn wenn Sie andere sed-Konstrukte als s, g und p (mit -n) verwenden, ist die awk-Alternative fast immer in fast jeder Hinsicht besser. Es dauerte 10+ Jahre, um sed + grep + shell + etc. Dinge tun, die sie nicht tun sollten, um das herauszufinden. Sehen Sie sich einfach an, wie einfach und konsistent ** und portabel ** die obigen awk-Skripte mit den sed-Alternativen verglichen werden. –

Verwandte Themen