Como posso apagar todo o texto entre chaves em um arquivo de texto de múltiplas linhas?

10

Exemplo:

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

Deve se tornar:

This is 
that wants
 anyway.

Encontrei algumas semelhante tópicos no fórum, mas eles não parece funcionar com chaves de várias linhas.

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

EDIT: As soluções parecem estar corretas, mas notei que meus arquivos originais incluem o aninhamento de colchetes. Então estou abrindo uma nova questão. Obrigado a todos: Como posso excluir todo o texto entre colchetes aninhados em um arquivo de texto de múltiplas linhas?

    
por Sopalajo de Arrierez 08.11.2014 / 23:48

3 respostas

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

Explicação:

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

    Isto lê todo o arquivo no espaço padrão.

    :again é um rótulo. N lê na próxima linha. $!b again ramifica de volta para o rótulo again 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 lidar com chaves aninhadas:

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

Explicação:

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

    Isso é o mesmo de antes: ele lê todo o arquivo.

  • :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, retorne ao rótulo b . Desta forma, o comando substituto é repetido até que todos os grupos de chaves sejam removidos.

por 09.11.2014 / 00:23
4

Perl:

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

Se você quiser editar no local

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

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

Isso manipulará aninhado:

perl -ne 'do {$b++ if $_ eq "{"; print if $b==0; $b-- if $_ eq "}"} for split //'
    
por 09.11.2014 / 00:12
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 ( T significa retornar à marca feita por : se a substituição não for feita)

Um pouco modifique para ser verdade se muitos curles saírem de uma linha

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

Remova todos os símbolos entre parênteses ( [^}] equal todos os símbolos exceto right bracket para tornar sed não desejado) e, se na linha permanecer left bracked - voltar para começar próxima linha adicionada se não houver right bracket .

    
por 09.11.2014 / 00:23