Apenas para fins de teste
sed ':1;s/([^()]*)//g;t1;s/.*[()].*/No/;t;s/.*/Yes/'
imprime "Sim" para o número correto e "Não" para o oposto para cada linha.
Gostaria de saber se, no meu arquivo, há um número correto de colchetes. Eu posso fazer meu arquivo parecer
(((()))()(()))
((()))()
Como posso usar sed
para calcular esses colchetes e imprimir sim ou não em vez da linha, se o número de colchetes estiver correto ou não?
sed ' s/.*/YES(&)/;:t
s/([^()]*)//g;tt
s/.....*/NO/'
Solução Perl simples:
perl -ne '1 while s/\(\)//g; print /[()]/ ? "Invalid\n" : "OK\n"' input.txt
Explicação: o loop while remove ()
até que não seja mais possível. Se houver parênteses, eles não foram balanceados.
O que se segue é uma tarefa mais complexa: marcar os primeiros parênteses não combinados :
#!/usr/bin/perl
use strict;
undef $/;
$_= <>; # slurp input
my $P = qr{[^()]*}; # $P = not parentheses
# repace matched parentheses by marks
while(s! \( ($P) \) !\cA$1\cB!gx){}
while(s!^ ($P) \( (.*) \) ($P) $ !$1\cB$2\cB$3!sgx){}
s!([()])! → $1!; # mark the first unmatched ()
y!\cA\cB!()!; # replace marks
print
Uso:
$ cat f
1(2(3(4(5)6)7)8(9)10(
11(12)13)14) (15 ( and )
(16(17(18)19)
20)21(22)23
$ parentesis f
1(2(3(4(5)6)7)8(9)10(
11(12)13)14) → (15 ( and )
(16(17(18)19)
20)21(22)23
Tags text-processing sed