【问题标题】:Excluding unknown number of multiple directories from find search (Unix)从查找搜索中排除未知数量的多个目录(Unix)
【发布时间】:2015-06-21 12:37:15
【问题描述】:

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

find . -name "*.sh"

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

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

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

我们将不胜感激每一个帮助/提示,​​谢谢!

【问题讨论】:

    标签: regex shell unix find


    【解决方案1】:

    您可以使用-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
    

    【讨论】:

    • 您好,感谢您的快速答复!我阅读了有关 -prune 选项的信息,但是如果我不知道需要排除多少个目录,我该如何使用它?这将是一个不错的解决方案,但我假设我无法根据需要排除的目录数量动态构建此命令。
    • @Pat 我回答了如何使用! -path 选项动态忽略目录,如果这对您不起作用但-prune 可以,请结合两个答案。在我插入! -path 的地方,你应该简单地插入-prune -o -type d -name
    • 更新了答案,希望能覆盖更多的基础。
    【解决方案2】:

    从文件中排除目录

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

    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.*'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 2013-08-14
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      相关资源
      最近更新 更多