【问题标题】:Shell script to delete directories older than n days用于删除超过 n 天的目录的 Shell 脚本
【发布时间】:2012-12-01 20:56:35
【问题描述】:

我的目录命名为:

2012-12-12
2012-10-12
2012-08-08

如何使用 bash shell 脚本删除超过 10 天的目录?

【问题讨论】:

  • 与他们的实际创建/修改时间有任何关系吗?因为find 不用看名字就可以做到...
  • 他们也应该有创建/修改时间
  • 你所说的“早于”是什么意思?您是指创建目录的时间、上次更改其内容的时间还是其他?请注意以下一些答案; ctime 是 inode 更改时间。对于目录,它会随着目录中文件的添加或删除而改变。

标签: bash shell


【解决方案1】:

这将为您递归执行:

find /path/to/base/dir/* -type d -ctime +10 -exec rm -rf {} \;

说明:

  • find: 查找文件/目录/链接等的unix命令。
  • /path/to/base/dir:开始搜索的目录。
  • -type d: 只查找目录
  • -ctime +10: 只考虑修改时间超过10天的
  • -exec ... \;:对于找到的每个这样的结果,在... 中执行以下命令
  • rm -rf {}:递归强制删除目录; {} 部分是查找结果从前一部分替换的位置。

或者,使用:

find /path/to/base/dir/* -type d -ctime +10 | xargs rm -rf

效率更高一点,因为它相当于:

rm -rf dir1 dir2 dir3 ...

相对于:

rm -rf dir1; rm -rf dir2; rm -rf dir3; ...

就像在-exec 方法中一样。


使用现代版本的find,您可以将; 替换为+,它会为您执行与xargs 调用等效的操作,传递适合每个exec 系统调用的尽可能多的文件:

find . -type d -ctime +10 -exec rm -rf {} +

【讨论】:

  • -mtime 对我来说更好,因为它检查内容更改而不是权限更改,否则这是完美的。
  • 我认为这也会删除基本目录本身
  • @OrGal 你是绝对正确的。为了防止这种情况,只需使用:find /path/to/base/dir/*.
  • 您可以使用 -maxdepth 1 忽略目录的内容
  • 如果要删除的文件夹过多,更有效的方法可能会适得其反:stackoverflow.com/questions/11289551/…。出于同样的原因,为了避免删除基本文件夹,最好使用-mindepth 1(而不是/path/to/folder/*)。
【解决方案2】:

find支持-delete操作,所以:

find /base/dir/* -ctime +10 -delete;

我认为文件也需要提前 10 天以上。没试过,可能有人在cmets中确认。

这里投票最多的解决方案是缺少-maxdepth 0,因此它会在删除每个子目录后调用rm -rf。这没有意义,所以我建议:

find /base/dir/* -maxdepth 0  -type d -ctime +10 -exec rm -rf {} \;

上面的-delete 解决方案不使用-maxdepth 0,因为find 会抱怨目录不为空。相反,它暗示 -depth 并从下往上删除。

【讨论】:

  • 我可以确认-delete 有效,但就像你说的,你只能用它来删除空目录,就像rmdir
【解决方案3】:

如果要删除/path/to/base下的所有子目录,例如

/path/to/base/dir1
/path/to/base/dir2
/path/to/base/dir3

但你不想删除根/path/to/base,你必须添加-mindepth 1-maxdepth 1选项,这将只访问/path/to/base下的子目录

-mindepth 1 从匹配项中排除根 /path/to/base

-maxdepth 1 匹配紧接在/path/to/base 下的子目录,例如/path/to/base/dir1/path/to/base/dir2/path/to/base/dir3,但它不会以递归方式列出这些子目录的子目录。所以这些示例子目录将不会被列出:

/path/to/base/dir1/dir1
/path/to/base/dir2/dir1
/path/to/base/dir3/dir1

等等。

所以,删除/path/to/base下所有超过10天的子目录;

find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf

【讨论】:

    【解决方案4】:

    rm -rf `find /path/to/base/dir/* -type d -mtime +10`
    

    更新,更快的版本:

    find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f
    

    【讨论】:

    • 这个很容易超过最大命令行长度。见xargs --show-limits
    • 如果文件名包含空格或其他特殊的 shell 字符,也将不起作用。
    • @Carpetsmoker -print0/-0 不处理特殊的 shell 字符吗?
    • 你说得对,xargs 版本会@mpen,但第一行不会。
    【解决方案5】:

    我正在努力使用上面提供的脚本和其他一些脚本来解决这个问题,尤其是当文件和文件夹名称包含换行符或空格时。

    终于偶然发现了 tmpreaper,到目前为止它对我们来说效果很好。

    tmpreaper -t 5d ~/Downloads
    
    
    tmpreaper  --protect '*.c' -t 5h ~/my_prg
    

    原文出处link

    具有像测试这样的功能,它递归地检查目录并列出它们。 能够删除符号链接、文件或目录,以及删除时特定模式的保护模式

    【讨论】:

      猜你喜欢
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 2015-04-01
      • 1970-01-01
      相关资源
      最近更新 更多