Como posso excluir todo o texto entre colchetes em um arquivo de texto com várias linhas?

10

Exemplo:

This is {
the multiline
text file }
that wants
{ to be
changed
} anyway.

Deve se tornar:

This is 
that wants
 anyway.

Eu encontrei alguns tópicos semelhantes no fórum, mas eles não parecem funcionar com colchetes de várias linhas.

Se possível, eu preferiria algum método de uma linha, como soluções baseadas em grep, sed, awk ... etc.

EDIT: As soluções parecem estar OK, mas notei que meus arquivos originais incluem aninhamento de colchetes. Então, eu estou abrindo uma nova pergunta. Obrigado a todos: como posso excluir todo o texto entre colchetes aninhados em um arquivo de texto com várias linhas?

Sopalajo de Arrierez
fonte
1
Tente istosed '/{/{:1;N;s/{.*}//;T1}' multiline.file
Costas

Respostas:

10
$ sed ':again;$!N;$!b again; s/{[^}]*}//g' file
This is 
that wants
 anyway.

Explicação:

  • :again;$!N;$!b again;

    Isso lê o arquivo inteiro no espaço do padrão.

    :againé um rótulo. Nlê na próxima linha. $!b againvolta ao againrótulo com a condição de que essa não seja a última linha.

  • s/{[^}]*}//g

    Isso remove todas as expressões entre chaves.

No Mac OSX, tente:

sed -e ':again' -e N -e '$!b again' -e 's/{[^}]*}//g' file

Chaves aninhadas

Vamos considerar isso como um arquivo de teste com muitas chaves aninhadas:

a{b{c}d}e
1{2
}3{
}
5

Aqui está uma modificação para manipular chaves aninhadas:

$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file2
ae
13
5

Explicação:

  • :again;$!N;$!b again

    É o mesmo de antes: ele lê o arquivo inteiro.

  • :b

    Isso define um rótulo b.

  • s/{[^{}]*}//g

    Isso remove o texto entre chaves, desde que o texto não contenha chaves internas.

  • t b

    Se o comando substituto acima resultou em uma alteração, volte para o rótulo b. Dessa maneira, o comando substituto é repetido até que todos os grupos de chaves sejam removidos.

John1024
fonte
Sua resposta parece perfeita. Desde que a nova pergunta que acabei de abrir (leia a pergunta original EDIT) não seja exatamente a mesma, acho que você deveria responder também. Seria bom com as regras do fórum?
Sopalajo de Arrierez
@ John1024, você pode mover sua edição por aqui, pois o OP postou uma nova pergunta sobre a mesma.
Ramesh
1
ESTÁ BEM. Copiei e modifiquei para usar o texto de exemplo na nova pergunta.
precisa saber é o seguinte
5

Perl:

perl -0777 -pe 's/{.*?}//sg' file

Se você deseja editar no local

perl -0777 -i -pe 's/{.*?}//sg' file

Isso lê o arquivo como uma única sequência e faz uma pesquisa e substituição global.

Isso manipulará o suporte aninhado:

perl -ne 'do {$b++ if $_ eq "{"; print if $b==0; $b-- if $_ eq "}"} for split //'
Glenn Jackman
fonte
Obrigado, isso foi muito útil! Isso me ajudou a resolver um problema com um script de construção para substituir o conteúdo de uma função dentro de minutos vs lutando com sed com ah..em, mais tempo, então eu vou admitir (hours..cough..cough)
Andrewd
4

Sed:

sed '/{/{:1;N;s/{.*}//;T1}' multiline.file

iniciado desde a linha com {e obter a próxima linha ( N) até que a substituição ( {}) possa ser feita ( Tsignifica retornar à marca feita por :se a substituição não for feita)

Um pouco modificado para ser verdadeiro se muitos enrolamentos entre uma linha

sed ':1; s/{[^}]*}// ; /{/ { /}/!N ; b1 }' multiline.file

Remova todos os símbolos entre parênteses ( [^}]igual a todos os símbolos, excetoright bracket para que sednão sejam gananciosos) e, se a linha permanecer left bracked- volte para começar com a próxima linha adicionada, se não houver right bracket.

Costas
fonte