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


2

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

谢谢!

Answers:


1

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

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

或者,您可以find完全跳过并让您的外壳进行查找。假设您的外壳是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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.