Excluir texto entre padrões que ocorrem em linhas diferentes [duplicado]

1

Eu sei que perguntas semelhantes foram feitas neste fórum, mas até agora Como posso ver, nenhum deles abordou o problema de os padrões estarem em linhas diferentes. Ou seja, dado um arquivo de texto

( one ) ( two ) (

three

)

four

Como posso excluir tudo o que está entre cada par '(' e ')', mesmo quando os elementos do par estão em linhas diferentes? O resultado desejado é

() () ()

four
    
por James 08.03.2018 / 20:49

4 respostas

2

Você pode usar perl: fazer slurp em toda a entrada como uma única string, e usar o s flag no comando s/// para indicar que as novas linhas devem ser tratadas como caracteres simples:

perl -0777 -pe 's/\(.*?\)/()/sg' <<END
( one ) ( two ) (

three

)

four
END
() () ()

four
    
por 08.03.2018 / 21:04
0

Python alternativa:

python -c 'import sys,re; print(re.sub(r"\([^()]+\)","()",sys.stdin.read().strip()))' <file

A saída:

() () ()

four
    
por 08.03.2018 / 21:10
0

Isso pode ser resolvido com uma simples máquina de estado em Python.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import fileinput
import sys

active = True
for line in fileinput.input():
    for ch in line:
        if ch == '(':
            sys.stdout.write(ch)
            active = False
        elif ch == ')':
            sys.stdout.write(ch)
            active = True
        elif active:
            sys.stdout.write(ch)

Solução executável

Uso:

$ echo '( one ) ( two ) (

three

)

four' | python /tmp/statemachine.py

Saída:

() () ()

four
    
por 08.03.2018 / 21:09
0

Usando sed e será gerenciado mesmo se houver parênteses aninhados.

sed -z 's/[^()]*)/)/g' infile

Entrada:

( (zero) one ) ( two ) (

three

)

((((nested))here)end) last
four

Saída:

( ()) () ()

(((()))) last
four
    
por 08.03.2018 / 21:59