Hallo, On Thu, 31 Jul 2003, Bernd Tannenbaum schrieb:
Ich möchte ans Ende einer jeden Zeile einer datei etwas anfügen.
Das hatten wir neulich doch erst... sed 's/$/Blablubb/'.
Ich entnehme folgendes: sed -e #So muß das ganze beginnen /muster/ #Falls ich nach einem Muster suchen will. #Lass ich es weg, werden alle zeilen genommen
Jein. Eigentlich sollte da 'ADRESSE' statt 'MUSTER' stehen. Denn eine Adresse "adressiert" einen Bereich: also ADRESSE := BEGINN,ENDE wobei ',ENDE' optional ist (in dem Fall umfasst der Bereich genau die Zeile, die durch 'BEGINN' ausgewaehlt wird. BEGINN und ENDE koennen jew. eine Zeilennummer (einfach die Zahl, z.B. '1' oder '10'), ein '$' fuer das Dateiende oder eine von '//' eingefasste Regexp sein. Wie die Adressen wirken, probiert man am besten mal mit einer einfachen Eingabe und dem Befehl 'p' durch (Z steht fuer Zeile): x='a\nb\nc\nd\ne\nf\n' echo -en "$x" | sed -n '1,1p' ### Bereich: von Z1 bis Z1 ist gleich: echo -en "$x" | sed -n '1p' ### Bereich: Z1 echo -en "$x" | sed -n '2,4p' ### Bereich: Z2 bis Z4 (inkl.) echo -en "$x" | sed -n '3,$p' ### Bereich: Z3 bis letzte Z echo -en "$x" | sed -n '1,$p' ### Bereich: Z1 bis letzte Z, also ### also aequivalent zu: echo -en "$x" | sed -n 'p' ### keine Adresse = alles x='abc\nbcd\ncde\ndef\nefg\nfhi\n' echo -en "$x" | sed -n '1,/e/' ### Bereich: Z1 bis zur ersten ### Zeile auf die die Regexp 'e' ### passt echo -en "$x" | sed -n '1,/^e/' ### Bereich: dito, andere Regexp echo -en "$x" | sed -n '/^b/,/e/p' ### Bereich: erste Zeile auf die '^b' ### passt bis erste Z. auf die ### 'e' passt echo -en "$x" | sed -n '/^b/,/^e/p' ### dito, andere End-Regexp echo -en "$x" | sed -n '/[bf]/p' ### Bereich: alle Zeilen auf die ### die RE passt So, jetzt wissen wir also, wie man mittels Adressen den folgenden Befehl aus bestimmte Bereiche der Eingabe einschraenkt. Allerdings nehmen einige sed-Befehle keine, oder nur eine Adresse (also nur 'BEGINN'). Darunter auch 'a'. Die meisten sind aber "Commands which accept address ranges", so z.B. 'p' und 's///'. echo -en "$x" | sed '/f/s/e/X/' ### Bereich: Zeilen auf die die ### Regexp 'f' passt, Befehl: ### substituiere das jew. erste ### 'e' der Zeile durch ein 'X'. Weitere Details zu 's///' wie die Modifizierer 'g' und 'p' finden sich in der manpage von sed.
a\text #Hier sage ich sed, er soll text anhängen
Aber an was? Les mal die manpage genau(er) unter Beruecksichtigung des obigen und der Ueberschrift "Zero- or One- address commands". ==== a \ text Append text, which has each embedded newline pre ceeded by a backslash. ==== Der sed-Befehl 'a' nimmt also 'keine' oder 'eine' Adresse. Und haengt _dort_ "text" an. echo -en "$x" | sed '/ef/a\
XXX' ### haenge _nach_ Zeilen auf die die ### Regexp 'ef' passt, den Text 'XXX' ### an.
Wichtig: das '\<newline>' gehoert zur Syntax von 'a'.[1] Den Unterschied von 'a' (fuer "append" ~ "anhaengen") zu 'i\ text' ("insert" ~ "einfuegen") sowie 'c\ text' ("change" ~ "aendern") kann man z.B. so einfach herausfinden (in $x steht immer noch das 'abc\nbcd...'): echo -en "$x" | sed '$a\ XXX' echo -en "$x" | sed '$i\ XXX' echo -en "$x" | sed '$c\ XXX'
sed -e /muster/a\text datei1 > datei2 Die shell meldet: sed: -e expression #1, char 8: Extra characters after command
Dein sed hat dieses[1] Feature offenbar nicht, dort gilt wie allgemein, dass nach so einem '\' _kein_ weiteres Zeichen ausser dem Zeilenumbruch folgen darf. Andernfalls wird es (AFAIK) ignoriert und sed beschwert sich dann zurecht ueber das 'atext', was keine gueltige Syntax ist. Korrekt waere also: sed -e '/muster/a\ text' datei1 > datei2 Den Zeilenumbruch gibt man in scripten einfach ein, auf der Kommandozeile laesst man einfach das schliessende "'" solange weg... Aber du willst ja an das _Zeilenende_ anfuegen, wie das geht siehe ganz oben. (Achtung: dort taucht das '$' als PATTERN im 's/PATTERN/REPLACEMENT/[MODIFIER]'-Befehl auf und steht _nicht_ fuer die letzte Zeile wie in einer Adresse, sondern wie in einer Adress-_Regexp_ fuer das Ende einer einzelnen Zeile! echo -e 'fubar\nfoo\nbar\nfoo\nbaz' \ | sed '/^bar$/,$s/o$/x/' ### | | ^- Zeilenende, da in Regexp ### | `- letzte Zeile ### `- Zeilenende, da in Regexp
Vielleicht hat auch einfach einer ne URL von einer brauchbaren Beispielseite. Beispiele wie "$a\ Fügt text an letzte Zeile an .....blablablub" nützen halt überhaupt nix, wenn man den Befehl in seiner kompletten syntax nicht hinbekommt.
manpage sehr genau lesen und ausprobieren! Und such mal nach Mails von mir hier in der Liste wo sed drin vorkommt... Ich hab hier (erst neulich) ausfuehrlich was geschrieben. -dnh [1] dass dort bei neueren GNU-sed (oder SuSE-GNU-sed) offenbar das newline fehlen darf ist mir neu. Portabel ist das aber sicher nicht, also ist es zu vermeiden. -- "And the Baron's tendency to speak in rhyme is even worse. It's like the Atreides are engaged in a brutal blood feud with Dr. Seuss." --Dave Helm on the Dune miniserie