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

时间:2015-04-15 13:52:02

标签: regex shell unix find

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

find . -name "*.sh"

但是我们走了:我想从这次搜索中排除一些(让我们说3 - dir1,dir2和dir3)目录。所以我想方设法做到这一点,但我只找到了静态的解决方案。这意味着我发现了很多解决方案,解释了如何从搜索搜索中精确排除3个目录。但不能确定要排除的目录数量 - 也许我需要排除3,可能是5甚至20。我想从输入文件中读取目录作为字符串(我已经有了那个读取逻辑到目前为止并且想要使用find动态排除这些文件。

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

是否有使用REGEX参数的解决方案?我目前正在使用SUN solaris并使用sh-Shell。

感谢您的每一个帮助/提示,​​谢谢!

2 个答案:

答案 0 :(得分:2)

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

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

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

我不确定你是什么意思"动态"但是,如果我正确地猜出你的意思,那么它不会比拥有一个命令行更具动态性,该命令行根据一组规则选择要排除的目录。如果要排除第四个字符为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

答案 1 :(得分:0)

从文件中排除目录

只需从文件中创建find命令:

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脚本中,当文件中只有一个目录时它也可以工作。

注意:要使其工作,文件名中不能有#,如果发生这种情况,请使用另一个分隔字符。=

编辑:由于您在逗号分隔的字符串中有dirs,因此解决方案更加容易。只需使用bash替换:

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

使用正则表达式

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

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