remova o texto após uma regex até o final da linha

remova o texto após uma regex até o final da linha

Eu tenho um arquivo como este

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

Quero cortar a linha logo após o ano);

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

isto não está a funcionar

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

Como eu poderia fazer isso com sed ou awk?

Responder1

Uma maneira válida de escrever o que você deseja é

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

Isso excluirá todos os caracteres de linha após a última ocorrência de yyyy);cada linha.

Sua tentativa foi

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

Mas, por causa do -Esinalizador que permite regex estendido, \( \)não delimite grupos correspondentes; em vez disso, eles correspondem aos parênteses literais do arquivo, enquanto ( )delimitam os grupos correspondentes. Portanto, o parêntese [0-9]{4})é incomparável e o sed reclama:

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

Responder2

Se sempre houver apenas um );, é bem simples:

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

se puder haver mais e você quiser remover tudo depois do último:

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

O seu não está funcionando porque você está tentando combinar um )seguido de 4 números ( \)[0-9]{4}), mas não tem isso em sua entrada. Acho que você estava tentando escrever algo assim:

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

Responder3

Com grep(assumindo a versão que você tem -oopção de suporte)

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

-oopção fará com grepque apenas as partes correspondentes sejam impressas. Portanto, isso não é exatamente o mesmo que sedcomando, pois as linhas que não contêm esse padrão não serão impressas.

Responder4

No seu exemplo, você corta cada linha após a última ;. Esta é uma operação simples sedque não requer nenhuma referência retroativa:

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

Ou com awk:

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

informação relacionada