【问题标题】:how to exclude all subdirectories of a given directory in the search path of the find command in unix如何在unix中find命令的搜索路径中排除给定目录的所有子目录
【发布时间】:2013-09-14 09:52:30
【问题描述】:

我需要备份我们服务器的所有目录层次结构,因此我需要列出服务器中某些目录的所有子目录。

问题在于其中一个子目录包含数以万计的子目录(仅包含子目录名称的文件可能需要数百兆字节,并且相应的查找命令需要很长时间)。

比如我有一个目录A和一个子目录A/a包含上万个子目录,我想用find命令列出A的所有子目录排除 A/a的所有子目录但不排除A/a本身

我使用this question 中的答案尝试了多种 -prune 变体,但均无济于事。

有没有办法在 UNIX 中使用 find 命令来执行此操作?

更新:

@devnull 的回答效果很好,但现在我遇到了另一个问题,所以我会稍微改进一下我的问题:

我使用了以下命令:

 find /var/www -type d \( ! -wholename "/var/www/web-release-data/*"  ! -wholename "/var/www/web-development-data/*" \)

出现的新问题是 find 由于某种原因仍在遍历"/var/www/web-release-data/""/var/www/web-development-data/" 的整个目录树,因此它非常慢,我担心它可能需要几个小时。

有没有办法让 find 完全排除那些目录而不遍历它们各自的目录层次结构

【问题讨论】:

  • 确定您想要A/a/,而不是A/a/foo/(文件夹)而不是A/a/x(文件)?
  • 是的。我只想找到文件夹而不是文件。我用了一个一般的例子,但是是的。我想要 A/a 但不是 A/a/*(文件和文件夹)。甚至排除 A/a 也可以(我尝试排除 A/a 但失败了)。
  • 对链接问题的接受答案正是您所需要的
  • 我尝试了三个答案,但对我不起作用。

标签: linux bash unix


【解决方案1】:

你试过rsync(1)吗?它有一个选项 --exclude=PATTERN 在这里可能会很好用:

rsync -avz --exclude=A/a <source> <target>

使用 rsync 你不需要使用find(1)

【讨论】:

    【解决方案2】:

    以下内容应该适合您:

    find A -type d \( ! -wholename "A/a/*" \)
    

    这将列出A 的所有子目录,包括A/a,但不包括A/a 的子目录。

    例子:

    $ mkdir -p A/{a..c}/{1..4}
    $ find A -type d \( ! -wholename "A/a/*" \)
    A
    A/c
    A/c/4
    A/c/2
    A/c/3
    A/c/1
    A/a
    A/b
    A/b/4
    A/b/2
    A/b/3
    A/b/1
    

    【讨论】:

    • +1 注意:这里不需要括号。他们只是让意图更清楚。
    • 如何使用你的方法排除两个子目录?
    • 为了排除上面例子中A/b的所有子目录,比如说find A -type d \( ! -wholename "A/a/*" ! -wholename "A/b/*" \)
    • 它看起来像它的工作,但我认为 find 仍在遍历 A/a 和 A/b 的子目录的整个列表,并且它仍然没有完成(它非常非常慢)。有没有办法让 find 完全跳过 A/a、A/b 而无需遍历它们的目录树?
    【解决方案3】:

    另一种解决方案:

    find A \! -path "A/a/*"
    

    如果您也不想使用a,请使用

    find A \! -path "A/a/*" -a \! -path "A/a"
    

    【讨论】:

      【解决方案4】:

      排除 2 个子目录:

      find . -type d ! -wholename "dir/name/*" -a ! -wholename "dir/name*"
      

      【讨论】:

        【解决方案5】:

        要回答您更新的问题,您可以这样做

        find /var/www -wholename "/var/www/web-release-data/*" -o -wholename "/var/www/web-development-data/*" -prune -o -type d -print
        

        【讨论】:

        • 我试过了,但仍然需要很长时间(我在十分钟后终止了该进程)。 find 仍然会遍历 /var/www/web-release-data/ 的所有目录树,其中包含数万个子目录。
        猜你喜欢
        • 2023-04-02
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        • 2021-10-01
        • 2011-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多