Em um sistema GNU:
grep -ErliZ "RegEx" . |
LC_ALL=C sed -z 's|/[^/]*$||' |
LC_ALL=C sort -zu |
tr 'find . -type f -print0 | LC_ALL=C gawk -v RS='grep -ErliZ "RegEx" . |
LC_ALL=C sed -z 's|/[^/]*$||' |
LC_ALL=C sort -zu |
tr 'find . -type f -print0 | LC_ALL=C gawk -v RS='%pre%' '
BEGIN{while ((getline < "/dev/stdin") > 0) ARGV[ARGC++] = $0}
FNR == 1 {dir = FILENAME; sub("/[^/]*$", ""); if (dir in found) nextfile}
/RegEx/ {found[dir]; print dir; nextfile}'
' '\n'
' '
BEGIN{while ((getline < "/dev/stdin") > 0) ARGV[ARGC++] = $0}
FNR == 1 {dir = FILENAME; sub("/[^/]*$", ""); if (dir in found) nextfile}
/RegEx/ {found[dir]; print dir; nextfile}'
' '\n'
Isso não é o ideal, pois ele procura RegEx
em todos os arquivos em um diretório, mesmo depois que uma correspondência já foi encontrada.
Para evitar isso e ainda evitar a execução de um grep
por diretório, com o GNU awk
, você poderia fazer:
%pre%
Estamos usando LC_ALL=C
, portanto, sub("/[^/]*$", "")
pode remover com segurança a parte do nome do arquivo, mas isso significa que a decodificação do texto nos arquivos não é feita de acordo com o mapa de caracteres do local. Se você souber que todos os caminhos de arquivo são texto válido na localidade atual, você poderá removê-lo. Ou você pode adicionar um -name '*'
a find
para ignorar nomes de arquivos que contenham seqüências de bytes que não formam caracteres válidos no idioma.