Может быть, что-то вроде:
grep -nPo '(?=(\((?:[^()]++|(?1))*\)) (?=\(VP)(?1) (?=\(NP)(?1))\(NP' |
cut -d: -f1 | uniq -c
То есть он соответствует (NP
при условии, что это начало (NP *) (VP *) (NP *)
, где мы использовать рекурсивное сопоставление PCRE для частей (...)
(часть (\ ((?: [^ ()] ++ | (? 1)) * \))
прямо со страницы руководства pcrepattern ).