Localizar com eficiência um arquivo / diretório baseado em palavras-chave

2

Eu tenho uma grande árvore de diretórios de construções. A pesquisa padrão find localiza o arquivo após um ou dois minutos. Eu gostaria que fosse daqui a alguns segundos.

Eu preciso encontrar um arquivo chamado foo.tar.gz . O arquivo pode residir em vários diretórios:

/mnt/build/my_project/master/<BUILD_NAME>/foo.tar.gz
/mnt/build/my_project/master/<BUILD_NAME>/<PREFIX>/foo.tar.gz
/mnt/build/my_project/main/<BRANCH>/<BUILD_NAME>/foo.tar.gz
/mnt/build/my_project/main/<BRANCH>/<BUILD_NAME>/PREFIX>/foo.tar.gz
/mnt/build/my_project/side/<BUILD_NAME>/foo.tar.gz
/mnt/build/my_project/side/<BUILD_NAME>/<PREFIX>/foo.tar.gz

Eu tentei várias instruções if [[ -f .. ]] , que reduzem o tempo de execução do script, mas há muitos casos para cobrir e manter o script se tornando um incômodo.

Eu também tentei estas instruções find :

find /mnt/build/my_project/ -ipath "*${BUILD_NAME}*" -name foo.tar.gz -type f
find /mnt/build/my_project/ -wholename "*${BUILD_NAME}*/foo.tar.gz" -type f

Como posso pesquisar com eficiência toda essa árvore de diretórios se um usuário fornecer um BUILD_NAME ?

Obrigado!

    
por Maxim_united 18.05.2015 / 15:52

1 resposta

1

Se você acabou de executar find , ele precisa passar por todos os subdiretórios para encontrar todos os arquivos. Parece que você espera que o arquivo esteja com uma profundidade baixa, então você pode passar o argumento -maxdepth para limitar a profundidade da pesquisa, por exemplo,

find /mnt/build/my_project/ -maxdepth 3 -wholename "*${BUILD_NAME}*/foo.tar.gz" -type f

Alternativamente, você pode pular find e fazer seu shell fazer a pesquisa. Assumindo que seu shell é bash (isso pode ser ajustado para ksh ou zsh):

shopt -s nullglob
candidates=(
  /mnt/build/my_project/*/"$BUILD_NAME"/*/foo.tar.gz
  /mnt/build/my_project/*/"$BUILD_NAME"/*/foo.tar.gz
  /mnt/build/my_project/*/*/"$BUILD_NAME"/*/foo.tar.gz
  /mnt/build/my_project/*/*/"$BUILD_NAME"/*/*/foo.tar.gz
)
case "${#candidates[@]}" in
  0) echo "No foo.tar.gz found";;
  1) echo "Got foo.tar.gz in ${candidates[0]}"
  *) echo "I don't know which foo.tar.gz to pick among" "${candidates[@]}";;
esac

Se você não pode limitar a profundidade da pesquisa, não há nenhuma maneira óbvia de podar partes da árvore. Talvez você possa pular alguns subdiretórios que você sabe que não são úteis, por exemplo para pular todos os diretórios .svn :

find /mnt/build/my_project/ -name .svn -prune -o -wholename "*${BUILD_NAME}*/foo.tar.gz" -type f -print
    
por 19.05.2015 / 00:48

Tags