Ich habe eine Datei wie diese
this is a year (2004); this text is not insteresting
singer elton john; month and year (December, 2005); blah blah
this another year (2007); irrelevant text
Ich möchte die Zeile direkt nach dem Jahr abschneiden);
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);
das funktioniert nicht
sed -E 's/\(.*\)[0-9]{4});\(.*\)/\2/' file
Wie könnte ich es mit sed oder awk machen?
Antwort1
Eine gültige Möglichkeit, das Gewünschte zu schreiben, ist
sed -E 's/(.*[0-9]{4}\);).*/\1/' file
Dadurch werden alle Zeilenzeichen nach dem letzten Vorkommen yyyy);
jeder Zeile gelöscht.
Ihr Versuch war
sed -E 's/\(.*\)[0-9]{4});\(.*\)/\2/' file
Aber aufgrund des -E
Flags, das erweiterte reguläre Ausdrücke aktiviert, \( \)
werden übereinstimmende Gruppen nicht abgegrenzt, sondern es werden wörtliche Klammern aus der Datei abgeglichen, während ( )
übereinstimmende Gruppen abgegrenzt werden. Die Klammer in [0-9]{4})
ist also nicht abgeglichen und sed beschwert sich:
sed: -e expression #1, char 28: Unmatched ) or \)
Antwort2
Wenn es immer nur einen gibt );
, ist es ganz einfach:
$ sed 's/);.*/);/' file
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);
wenn es noch mehr sein können und du alles nach dem letzten entfernen willst:
$ sed -E 's/(.*)\);.*/\1);/' file
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);
)
Ihrs funktioniert nicht, weil Sie versuchen, ein gefolgt von 4 Zahlen ( ) zuzuordnen, \)[0-9]{4}
aber das haben Sie nicht in Ihrer Eingabe. Ich glaube, Sie wollten so etwas schreiben:
$ sed -E 's/(.*[0-9]{4}\);).*/\1/' file
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);
Antwort3
Mit grep
(vorausgesetzt, Ihre Version unterstützt -o
diese Option)
$ grep -oE '.*[0-9]{4});' file
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);
-o
Option bewirkt, grep
dass nur die übereinstimmenden Teile gedruckt werden. Dies ist also nicht ganz dasselbe wie sed
der Befehl, da die Zeilen, die dieses Muster nicht enthalten, nicht gedruckt werden.
Antwort4
In Ihrem Beispiel schneiden Sie jede Zeile nach der letzten ab ;
. Dies ist eine einfache Operation, sed
die keine Rückverweise erfordert:
$ sed 's/;[^;]*$/;/' file
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);
Oder mit awk
:
awk -F ';' 'BEGIN { OFS=FS } { $NF=""; print }' file