$ 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).