根据关键字高效查找文件/目录

根据关键字高效查找文件/目录

我有一个很大的构建目录树。标准find搜索在一两分钟后找到该文件。我希望它在几秒钟内完成。

我需要找到一个名为foo.tar.gz.该文件可以驻留在不同的目录中:

/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

我尝试了很多if [[ -f .. ]]语句,这些语句确实减少了脚本运行时间,但是有太多的情况需要涵盖,并且维护脚本变得很麻烦。

我也尝试过这些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

如果用户提供 ,我如何有效地搜索所有目录树BUILD_NAME

谢谢!

答案1

如果您只是运行find,它必须遍历所有子目录才能找到所有文件。看起来您希望文件的深度较低,因此您可以传递参数-maxdepth来限制搜索的深度,例如

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

或者,您可以find完全跳过并让您的 shell 进行查找。假设您的 shell 是 bash(可以针对 ksh 或 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

如果无法限制搜索深度,则没有明显的方法来修剪树的某些部分。也许您可以跳过一些您知道没有用的子目录,例如跳过所有.svn目录:

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

相关内容