удалить текст после регулярного выражения до конца строки

удалить текст после регулярного выражения до конца строки

У меня есть такой файл

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

Я хочу сократить очередь сразу после года);

this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);

Это не работает

sed -E 's/\(.*\)[0-9]{4});\(.*\)/\2/' file

Как это сделать с помощью sed или awk?

решение1

Действенный способ написать то, что вы хотите, это

sed -E 's/(.*[0-9]{4}\);).*/\1/' file

Это приведет к удалению всех символов строки после последнего вхождения yyyy);каждой строки.

Ваша попытка была

sed -E 's/\(.*\)[0-9]{4});\(.*\)/\2/' file

Но из-за -Eфлага, который включает расширенное регулярное выражение, \( \)не разграничивают совпадающие группы, вместо этого они сопоставляют буквальные скобки из файла, при этом ( )разграничивая совпадающие группы. Поэтому скобки в [0-9]{4})не сопоставлены, и sed жалуется:

sed: -e expression #1, char 28: Unmatched ) or \)

решение2

Если всегда только один );, то все довольно просто:

$ sed 's/);.*/);/' file 
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);

если их может быть больше и вы хотите удалить все после последнего:

$ sed -E 's/(.*)\);.*/\1);/' file 
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);

Ваш не работает, потому что вы пытаетесь сопоставить a )с последующими 4 числами ( \)[0-9]{4}), но у вас этого нет в вашем вводе. Я думаю, вы пытались написать что-то вроде этого:

$ 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);

решение3

С grep(предполагается, что версия, которая у вас есть, поддерживает -oэту опцию)

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

-oопция приведет grepк печати только соответствующих частей. Таким образом, это не совсем то же самое, что sedкоманда, поскольку строки, не содержащие этот шаблон, не будут напечатаны.

решение4

В вашем примере вы вырезаете каждую строку после последней ;. Это простая операция, sedкоторая не требует никаких обратных ссылок:

$ sed 's/;[^;]*$/;/' file
this is a year (2004);
singer elton john; month and year (December, 2005);
this another year (2007);

Или, с awk:

awk -F ';' 'BEGIN { OFS=FS } { $NF=""; print }' file

Связанный контент