如何删除包含今天至少 n 天前修改的所有文件的顶级目录?

如何删除包含今天至少 n 天前修改的所有文件的顶级目录?

考虑以下文件夹结构

dir
    sandbox1
        mywebsite file 
        ...
    sandbox2
        mywebsite file
        ...

我的同事创建了数千个这样的沙盒目录。

由于我们的 inode 即将用完,我们决定删除 20 天未修改内容的沙盒目录。

例如。

dir
    sandbox1 (modified 23 days ago)
        mywebsite file (modified 22 days ago)
        ... (modified 24 days ago)
    sandbox2 (modified 23 days ago)
        mywebsite file (modified 19 days ago)
        ...

在这种情况下,sandbox1 将被删除,因为它已经 20 天没有被修改,并且其内容也已经 20 天没有被修改

Sandbox2 不会被删除,因为其中有 19 天前修改的内容

我知道

find /dir/ -maxdepth 1 -mtime +n 

查找所有修改过至少 n 天的目录,但不会反映每个目录内的内容。

有没有办法找到所有目录,使得目录及其内容 n 天内未被修改过?

任何帮助,将不胜感激。

答案1

如果文件修改时间对你来说很重要,那么你需要查看文件修改时间,而不是其父目录的修改时间。后者仅在以下情况下才会更改:结构目录更改(即创建、移动/重命名或取消链接文件)。文件更改内容不会反映在父目录的时间戳中。

因此我们可以找到所有最近修改的内容(少于 20×24 小时前)文件在目录树中:

find /some/path -type f -mtime -20

我们可以限制输出以仅显示唯一的目录名称:

find /some/path -type f -mtime -20 -printf '%h\n' | uniq

查找所有没有最近修改文件的目录

如果我们需要查找所有没有最近修改的深层条目的目录,情况会变得更加棘手,因为我们需要计算倒置集,即树内所有目录的集合与先前计算的集合的集合差。我们可以轻松地使用该-printf操作对输出进行分区,find至少列出我们需要的所有数据:

find /some/path -mindepth 1 \( -type d -printf '+%p\n' \) -o \( -type f -mtime -20 -printf '-%h\n' \) | uniq

不幸的是,集合操作不是可以在 shell 脚本中轻松完成的操作,因此我编写了一个 Python 程序来对上一个命令的输出进行操作find

#!/usr/bin/env python3
import sys, os.path
from itertools import filterfalse   

def parent_dir_generator( path ):
    while path:
        yield path
        path = os.path.dirname(path)

all_dirs = list()
keep_dirs = set()
keep_dir_parents = set()

for line in filter(bool, map(lambda s: s.rstrip('\n'), sys.stdin)):
    path = line[1:]
    if path.startswith('./'):
        path = path[2:]

    if line.startswith('+'):
        all_dirs.append(path)
    elif line.startswith('-'):
        keep_dirs.add(path)
        keep_dir_parents.update(parent_dir_generator(path))

diff_dirs = filterfalse(
    lambda path: any(map(keep_dirs.__contains__, parent_dir_generator(path))),
    filterfalse(keep_dir_parents.__contains__, all_dirs))

print(*diff_dirs, sep='\n')

假设上面的程序在,~/tree-difference.py我们可以像这样使用它:

find /some/path -mindepth 1 -depth \( -type d -printf '+%p\n' \) -o \( -type f -mtime -20 -printf '-%h\n' \) | python3 ~/tree-difference.py

验证结果

您可能想验证您(或我)没有犯错误,没有意外删除最近修改的文件。幸运的是,我们可以使用原始find命令的变体来检查 返回的所有目录tree-difference.py。它列出了其中所有最近修改的文件,因此空输出意味着一切都按计划进行。如果我们有很多文件,这可能需要相当长的时间。

以下命令从输出tree-difference.py(使用管道或中间文件)获取输入:

xargs -rd '\n' -I{} -- find {} -mindepth 1 -type f -mtime -20

删除找到的目录

这个很简单。输入是 的输出tree-difference.py

xargs -rd '\n' -- rm -rf --

如果rm抱怨目录不存在,那是因为您忘记了作为输入的命令-depth中的选项。findtree-difference.py

相关内容