我有一个很大的构建目录树。标准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