Eu preciso pesquisar uma hierarquia de diretórios bastante grande para arquivos regulares com nomes que correspondam a um padrão de globbing de nome de arquivo específico. A hierarquia é tão grande (muito profunda e com alguns diretórios enormes) que levaria muito tempo para adotar uma abordagem ingênua:
find /top/dir -type f -name 'pattern'
(Onde pattern
está algum padrão como *proj*.tgz
.)
Devido à natureza da estrutura de diretórios, sei que poderia introduzir uma otimização para podar a árvore de pesquisa se find
encontrasse um arquivo em um diretório. Por exemplo, encontrar um ou vários arquivos em um diretório específico significaria que eu não precisaria examinar nenhum dos subdiretórios desse diretório específico para outras correspondências.
Como aplicar -prune
a um arquivo normal não está fazendo a coisa certa, não posso simplesmente fazer
find /top/dir -type f -name 'pattern' -prune
Descrição: Como evito pesquisar os subdiretórios do diretório que contém o(s) arquivo(s) que corresponde(m) ao padrão?
Pode-se chamar um script in-line para cada diretório. O script verificaria se o padrão corresponde a algum arquivo regular no diretório. Se o padrão corresponder, ele gera (no caso geral, processa em vez de apenas imprimir) os nomes de caminho correspondentes e remove o diretório pai da árvore de pesquisa:
Estou usando o
zsh
shell para o script in-line para acessar os qualificadores globbing desse shell. O qualificador usado aqui,(.N)
, garante que apenas arquivos regulares correspondam ao padrão e remove o padrão se não houver arquivos correspondentes.Usando
bash
para o script em linha:Ou seja, deixe o script em linha fazer um loop sobre os nomes que correspondem ao padrão no diretório específico e, se algum nome corresponder a um arquivo regular, processe-o e defina um "sinalizador". Se o sinalizador estiver definido no final, remova o diretório pai.
Percorra a hierarquia de diretórios, e em cada um podar a árvore se o arquivo sinalizador (
pattern
) for encontrado, mas caso contrário procure os arquivos desejados (*proj*.tgz
)Acabei escrevendo uma versão mais complexa disso que me permitiu ver o que estava acontecendo. Obviamente, tive que alterar
/top/dir
,pattern
e*proj*.tgz
para itens relevantes localmente.) Vou incluí-lo aqui para a posteridadeA solução real requer o não-POSIX
find -maxdepth
. A versão de depuração também requer não POSIXfind -printf
. Existe uma abordagem alternativa para implementação-maxdepth
que satisfaça o POSIX, mas não a usei aqui; o código é opaco o suficiente como é.