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 -E
sinalizador 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 -o
opçã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);
-o
opção fará com grep
que apenas as partes correspondentes sejam impressas. Portanto, isso não é exatamente o mesmo que sed
comando, 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 sed
que 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