У меня есть такой файл
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