从查找搜索中排除未知数量的多个目录 (Unix)

Excluding unknown number of multiple directories from find search (Unix)

我有一个正在寻找一些文件的 shell 脚本,它工作正常:

find . -name "*.sh"

但我们开始吧:我想从搜索中排除一些目录(比方说 3 - dir1、dir2 和 dir3)。所以我寻找方法来做到这一点,但我只找到了 "static" 的解决方案。这意味着我找到了很多解释如何从查找搜索中准确排除 3 个目录的解决方案。但不能确定要排除的目录数量——也许我需要排除 3 个、5 个甚至 20 个。我想从输入文件中读取目录作为字符串(到目前为止我已经有了读取逻辑)和想动态地使用 find 排除那些文件。

澄清一下:我有一个这样的字符串:'/home/dir1,/dir2,./dir3,./sub/dir4' 我不知道这个会包含多少个目录字符串,但我想排除所有这些。

有没有使用REGEX参数之类的解决方案?我目前正在使用 SUN solaris 并使用 sh-Shell.

每help/hints将不胜感激,谢谢!

您可以使用 -prune 排除路径,直到只剩下您想要的路径。

find . -iregex '.*/.git/.*' -prune -o -type d -name 'CVS' -prune -o ... whatever -print

我正在使用不同的谓词来证明您完全支持 find 支持的谓词。如果这些,-iregex 不区分大小写地对完整路径名应用正则表达式; -type d -name CVS 匹配名称恰好为 CVS 的目录,等等。显然,请参阅 the manual 了解更多信息。为了解决您的问题,您可以根据需要添加任意数量的内容。

我不确定你所说的 "dynamically" 是什么意思,但如果我猜对了你的意思,它不会比使用命令行根据一组选择要排除的目录更具动态性的规则。如果要排除第四个字符为W的目录,请添加-o -name '???W*' -prune。条件多了再补充。

另一方面,您可以通过枚举要排除的目录来创建完全静态的命令。您或许可以创建一个脚本来为您创建最终的 find 命令行,例如

printf '%\n' one/directory path/to/another hey/yes/one/more etc/and/so/forth |
sed "s%.*%-type d -path '&' -prune -o %" |
xargs -i find . {} print

从文件中排除目录

只需从文件创建查找命令:

exclude=' ! -path "./'$(paste -s -d'#' dirstoexclude | sed 's/#/\/\*" ! -path "\.\//g')'/*"'
find . -type f ${exclude}

将您的目录存储在 dirsttoexclude 中,不带前导 ./ 和尾随 /*,它们将被添加。用法示例:

$ mkdir test && cd test
$ mkdir test1 test2 test3
$ touch test1/a test2/b test3/c
$ find -type f
./test2/b
./test1/a
./test3/c
$ cat exclude\ dirs
test1
test2
$ exclude=' ! -path "./'$(paste -s -d'#' "exclude dirs" | sed 's/#/\/\*" ! -path "\.\//g')'/*"'
$ find . -type f $exclude
./test3/c

您可以将它包装在一个 shell 脚本中,当文件中只有一个目录时它应该也能工作。

注意:要使其正常工作,您的文件名中不能有 #,如果可能发生,请使用另一个分隔符。=

编辑:由于您在逗号分隔的字符串中有目录,因此解决方案更加简单。只需使用 bash 替代:

exclude=' ! -path "./'${string//,/\/*\" ! -path \"./}'/*"'

使用正则表达式

您也在 find 中使用正则表达式,所以您需要做的就是检查是否存在可以满足您需求的正则表达式(这是可能的)。你这样使用它:

 find -regextype sed -regex '.*some *regex.*'