find命令问题-如何在不列出基目录的情况下列出目录下的子目录和文件

find命令问题-如何在不列出基目录的情况下列出目录下的子目录和文件

Find 命令 - 如何仅列出目录下的子目录和文件,而不列出作为参数传递的基目录。

例子:

find /abc/def/ghi -mtime +10 

上面的命令输出还会导致基本目录与其中的子目录和文件一起列出。

/abc/def/ghi 
/abc/def/ghi/fff
/abc/def/ghi/abc.txt

我希望输出如下所示。

/abc/def/ghi/fff
/abc/def/ghi/abc.txt

这个问题的原因是 -find命令输出被用来递归地删除目录和文件。因此,如果基本目录/abc/def/ghi10 天没有使用,它也会被列出并最终被删除。

find /abc/def/ghi -mtime +10 -exec rm -rf {} \;

答案1

查找早于阈值的文件,然后删除空目录。

请注意,该$base变量使用了四次(每个语句两次)。该-path "$base/*"操作确保我们最终不会删除$base自身 -*匹配目录树中除最顶层.或之外的任何位置的每个项目..

base=/abc/def
find "$base/" -path "$base/*" -type f -mtime +10 -exec rm -f {} +
find "$base/" -depth -path "$base/*" -type d -exec rmdir {} + 2>/dev/null

答案2

您可以find通过两种方式要求显式忽略顶级搜索路径。

  1. 使用标准-path测试来避免作用于顶级搜索路径:

    find /abc/def/ghi ! -path /abc/def/ghi ...other tests/actions...
    

    这会找到顶级搜索路径,但会避免对其进行操作,因为它与-path测试使用的路径名完全匹配。这! 颠倒了测试的意义。

  2. 使用非标准但普遍实施的-mindepth测试:

    find /abc/def/ghi -mindepth 1 ...other tests/actions...
    

    这使得find忽略位于“深度零”的所有路径名,即顶级搜索路径本身。

  3. 第三种方法,取决于您实际想要做什么,是对目录不感兴趣(因为顶级搜索路径通常是目录路径):

    find /abc/def/ghi ! -type d ...other tests/actions...
    

现在,看看您想要做什么,您似乎想要清理过去 10 天内没有添加或删除新内容的目录。最安全的方法是查看文件具体来说,并删除旧的文件。完成此操作后,您可以删除最终为空的目录。

您不想依赖目录的时间戳的原因是这些时间戳没有说明文件何时进入 子目录被添加或删除。由于时间戳旧而删除目录可能会意外删除较低子目录中的新文件。

我可能会用类似的东西

find /abc/def/ghi -type f -mtime +10 -delete
find /abc/def/ghi ! -path /abc/def/ghi -type d -empty -delete

! -path /abc/def/ghi如果您同意删除顶级搜索路径(如果它是空的),则可以删除该路径。

由于-empty测试和-delete操作是非标准的,因此以下是如何使用标准做同样的事情find

find /abc/def/ghi -type f -mtime +10 -exec rm -f {} +
find /abc/def/ghi -depth ! -path /abc/def/ghi -type d -exec rmdir {} \; 2>/dev/null

第一个命令应该是直接的。它收集旧文件并rm -f批量调用它们。

第二个命令用于-depth执行深度优先搜索。我们这样做是因为

  1. 我们不想find尝试进入我们刚刚删除的目录,并且
  2. 一个目录可以变得一旦我们删除了其中的其他目录,它就为空。

第二个命令也尝试rmdir运行全部目录(除了顶级搜索路径)。这会失败对于非空目录,因此我们将错误流重定向到/dev/null忽略诊断消息。

为了只调用rmdir真正的空目录,我们可以使用

find /abc/def/ghi -depth ! -path /abc/def/ghi -type d \
    -exec bash -O dotglob -O nullglob -c '
    for dirpath do
        set -- "$dirpath"/*
        [ "$#" -gt 0 ] && rmdir "$dirpath"
    done' bash {} +

这调用了一个简短的内联bash脚本,该脚本迭代目录,并为每个目录尝试扩展*其中的通配模式。如果它扩展为根本没有名称,则该目录将被删除。

答案3

没关系..我自己几乎没有尝试和错误就得到了答案。

find /abc/def/ghi/* -mtime +10 -exec rm -rf {} \;

相关内容