$ pcregrep -Mo 'pin\(ABC\) (\{([^{}]++|(?1))*\})' file
pin(ABC) {
a b c d e f {
abc
}
}
Se você não tem pcregrep
mas tem o GNU grep
e ele foi construído com suporte a padrões PCRE e seu arquivo não é muito grande e não contém caracteres NUL, você pode fazer:
grep -zPo 'pin\(ABC\) (\{([^{}]++|(?1))*\})' file
Aqueles ( pcregrep
e grep -P
) estão usando padrões PCRE que suportam operadores regex recursivos.
pcregrep -M
ativa o modo de múltiplas linhas (onde pcregrep
pode extrair várias linhas conforme necessário ao corresponder ao regexp) e grep -z
informa que os registros são separados por NUL em vez de linhas .
O truque acima está no operador (?1)
, o que significa os regexps dentro do primeiro grupo paren , por isso temos um regexp recursivo: estamos combinando {
seguido por uma seqüência de 0 ou mais ( *
) seqüências de caracteres não-chave ( [^{}]++
, ++
sendo a versão possessiva de +
) ou o regexp na% externa(...)
novamente ( {
seguido por ...).
Veja a página man de pcrepattern
para detalhes. Isso é copiado quase literalmente de um exemplo lá.
Usando perl
:
perl -l -0777 -ne 'print $& while /pin\(ABC\) (\{([^{}]++|(?1))*\})/g'
(como para grep
, ele pega todo o arquivo na memória).