Com o GNU grep
construído com suporte a PCRE, você poderia:
find . -size +0 -type f -exec \
grep -zLP '\A((?:[^][<>{()}]++|<(?1)>|\{(?1)\}|\[(?1)\]|\((?1)\))*+)\z' {} +
Para encontrar esses arquivos (supondo que eles não contenham bytes NUL e que cada um seja pequeno o suficiente para caber todo na memória).
Ou chame perl
diretamente (permitindo arquivos com bytes NUL):
find . -size +0 -type f -exec perl -l -0777 -ne 'print $ARGV unless
/^((?:[^][<>{()}]++|<(?1)>|\{(?1)\}|\[(?1)\]|\((?1)\))*)$/' {} +
Alguns operadores específicos de perl / PCRE:
-
\A
e\z
correspondem respectivamente no início e no final do assunto. Como^
e$
(ou com a opção-x
), mas sem ambigüidade quando o assunto é multilinha (necessário em algumas versões do GNUgrep
). -
++
e*+
são as versões sem retrocesso dos operadores+
e*
. Aqui, o mecanismo de regexp não ajuda muito a encontrar uma correspondência quando sabemos que não é possível. -
(?1)
refere-se ao regexp no grupo de captura correspondente. Isso permite regexps recursivos. -
(?:...)
, o mesmo que(...)
, mas apenas para agrupamento (sem captura ...)
Note que ele encontra grandes proporções dos arquivos *.tex
no meu sistema, pois <
/ >
são usados para operadores de comparação no TeX e alguns desses caracteres são encontrados inigualáveis em comentários ou escapados.