Text nach einem regulären Ausdruck bis zum Zeilenende entfernen

Text nach einem regulären Ausdruck bis zum Zeilenende entfernen

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 -EFlags, 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 -odiese Option)

$ grep -oE '.*[0-9]{4});' file
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);

-oOption bewirkt, grepdass nur die übereinstimmenden Teile gedruckt werden. Dies ist also nicht ganz dasselbe wie sedder 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, seddie 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

verwandte Informationen