"find -mtime +5 | xargs rm -rf" 销毁整个目录,即使存在超过 5 天的文件
"find -mtime +5 | xargs rm -rf" destroying whole directories, even when files newer than 5 days exist
我有一系列这样的文件夹、子文件夹和文件:
year_folder
month1_folder
day1_folder
filea, fileb
day2_folder
filea
month2_folder
我想删除超过 X 天的文件夹和文件。
我试过了
find /c/Documents/year_folder -mtime +5 | xargs rm -rf
此命令行在我的测试文件夹(在我的计算机本地)上完美运行。
但是当我 运行 synology 上的脚本时,它以某种方式删除了整个 year_folder.
不幸的是,我不知道如何在 synology 服务器上测试我的脚本以了解我做错了什么。
使用 GNU 扩展
把它分成两部分:
删除超过五天的文件(仅限!)
# for GNU find; see below for POSIX
find "$root" -type f -mtime +5 -delete
删除空目录
# for GNU find; see below for POSIX
find "$root" -depth -type d -empty -delete
当您使用 rm -rf
时,如果目录本身在五天内没有更新,您将删除整个目录。但是,如果您创建或修改 a/b/c
,那不会更新 a
的修改时间(或者,在不需要更新目录本身的修改的情况下,甚至a/b
) -- 因此,当你递归应用它时,你的 "modification time older than five days" 规则是破坏性的。
以上唯一需要注意的是,它可能不会在运行处删除多层空目录——也就是说,如果a/b/c
是空的,而a/b
是c
以外为空,则在第一个 运行 上只能删除 c
,并且在删除 a/b
之前可能需要另一次调用。
支持基线POSIX
POSIX find
不支持 -delete
。因此,第一个命令变为:
find "$root" -type f -mtime +5 -exec rm -rf -- {} +
同样不支持-empty
。因为 rmdir
在传递非空目录时会失败,但是,让那些引用非空目录的实例失败很容易:
find "$root" -depth -type d -exec rmdir -- {} +
如果您不愿意这样做,事情就会变得更加棘手。使用 shell 来测试每个目录是否为空的实现可能如下所示:
find "$root" -depth -type d -exec sh -c '
rmdir_if_empty() {
dir=
set -- "$dir"/* # replace argument list w/ glob result
[ "$#" -gt 1 ] && return # globbed to multiple results: nonempty
{ [ -e "" ] || [ -L "" ]; } && return # globbed to one result that exists: nonempty
rmdir -- "$dir" # neither of the above: empty, so delete.
}
for arg; do
rmdir_if_empty "$arg"
done
' _ {} +
我有一系列这样的文件夹、子文件夹和文件:
year_folder
month1_folder
day1_folder
filea, fileb
day2_folder
filea
month2_folder
我想删除超过 X 天的文件夹和文件。 我试过了
find /c/Documents/year_folder -mtime +5 | xargs rm -rf
此命令行在我的测试文件夹(在我的计算机本地)上完美运行。 但是当我 运行 synology 上的脚本时,它以某种方式删除了整个 year_folder.
不幸的是,我不知道如何在 synology 服务器上测试我的脚本以了解我做错了什么。
使用 GNU 扩展
把它分成两部分:
删除超过五天的文件(仅限!)
# for GNU find; see below for POSIX find "$root" -type f -mtime +5 -delete
删除空目录
# for GNU find; see below for POSIX find "$root" -depth -type d -empty -delete
当您使用 rm -rf
时,如果目录本身在五天内没有更新,您将删除整个目录。但是,如果您创建或修改 a/b/c
,那不会更新 a
的修改时间(或者,在不需要更新目录本身的修改的情况下,甚至a/b
) -- 因此,当你递归应用它时,你的 "modification time older than five days" 规则是破坏性的。
以上唯一需要注意的是,它可能不会在运行处删除多层空目录——也就是说,如果a/b/c
是空的,而a/b
是c
以外为空,则在第一个 运行 上只能删除 c
,并且在删除 a/b
之前可能需要另一次调用。
支持基线POSIX
POSIX find
不支持 -delete
。因此,第一个命令变为:
find "$root" -type f -mtime +5 -exec rm -rf -- {} +
同样不支持-empty
。因为 rmdir
在传递非空目录时会失败,但是,让那些引用非空目录的实例失败很容易:
find "$root" -depth -type d -exec rmdir -- {} +
如果您不愿意这样做,事情就会变得更加棘手。使用 shell 来测试每个目录是否为空的实现可能如下所示:
find "$root" -depth -type d -exec sh -c '
rmdir_if_empty() {
dir=
set -- "$dir"/* # replace argument list w/ glob result
[ "$#" -gt 1 ] && return # globbed to multiple results: nonempty
{ [ -e "" ] || [ -L "" ]; } && return # globbed to one result that exists: nonempty
rmdir -- "$dir" # neither of the above: empty, so delete.
}
for arg; do
rmdir_if_empty "$arg"
done
' _ {} +