Extrair texto incluindo parens

3

Eu tenho um texto assim:

Sentence #1 (n tokens):
Blah Blah Blah
[...
 ...
 ...]
( #start first set here
 ... (other possible parens and text here)
 ) #end first set here

(...)
(...)

Sentence #2 (n tokens):

Eu quero extrair o segundo conjunto de parênteses (incluindo tudo no meio), ou seja,

(
 ... (other possible parens here)
)

Existe uma maneira básica de fazer isso? Eu tentei o simples

 's/(\(.*\))//'
    
por knk 25.09.2014 / 23:08

2 respostas

8

Isso vai fazer isso. Há provavelmente uma maneira melhor, mas esta é a primeira abordagem que veio à mente:

echo 'Sentence #1 (n tokens):
Blah Blah Blah
[...
 ...
 ...]
(
 ... (other possible parens here)
 )

(...)
(...)

Sentence #2 (n tokens):
' | perl -0777 -nE '
    $wanted = 2; 
    $level = 0; 
    $text = ""; 
    for $char (split //) {
        $level++ if $char eq "(";
        $text .= $char if $level > 0;
        if ($char eq ")") {
            if (--$level == 0) {
                if (++$n == $wanted) { 
                    say $text;
                    exit;
                }
                $text="";
            }
        }
    }
'

saídas

(
 ... (other possible parens here)
 )
    
por 25.09.2014 / 23:49
4

A resposta de Glenn é boa (e provavelmente mais rápida para grandes entradas), mas para o registro, o que Glenn propõe é totalmente possível no bash também. Foi uma questão relativamente simples de portar sua resposta para pura bash em apenas alguns minutos:

s='Sentence #1 (n tokens):
Blah Blah Blah
[...
 ...
 ...]
(
 ... (other possible parens here)
 )

(...)
(...)

Sentence #2 (n tokens):
'
wanted=2
level=0
text=""
for (( i=0; i<${#s}; i++ )); do
    char="${s:i:1}"
    if [ "$char" == "(" ]; then (( level++ )) ; fi
    if (( level > 0 )); then text+="$char"; fi
    if [ "$char" == ")" ]; then
        if (( --level == 0 )); then
            if (( ++n == wanted )); then
                echo "$text"
                exit
            fi
            text=""
        fi
    fi
done
    
por 26.09.2014 / 02:00