我每天在自己的目录中创建备份文件:
2020-04-01
2020-04-02
2020-04-03
很快
如何编写代码来删除旧目录及其内容。到目前为止,我有下面的代码,它正在删除目录,但它不够智能。因为如果我将目录中的文件复制到另一个目录中,修改日期将会改变:
find ~/delete/* -type d -ctime +6 -exec rm -rf {} \;
答案1
要按目录名称删除目录bash
:
#!/bin/bash
shopt -s nullglob
date=$(date -d '-7 day' '+%F')
for path in ~/delete/[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]; do
if [[ -d $path && ${path##*/} < $date ]]; then
echo rm -rf "$path"
fi
done
这将循环匹配 YYYY-MM-DD 模式的路径名,并跳过非目录和名称未按字典顺序排序在当前日期 - 7 天之前的目录。
启用nullglob
后,如果没有匹配的文件/目录并且不执行循环内的代码,则路径名模式将扩展为空字符串。
如果输出看起来符合预期,请删除echo
并再次运行脚本以真正删除这些目录。
答案2
您的标题有点误导,因为您实际上无法使用时间戳,并且必须信任这些名称。
一个可能的解决方案
keepAfter=$(date -d '-6 days' +'%F')
for d in */
do
[[ "$d" < "$keepAfter"/ ]] && echo rm -rf $d
done
echo
对结果满意时删除
答案3
另一个解决方案:
d=/path/to/deleted;
printf '%s\n' $d/*/ | awk -v upTo="$d/$(date -d '-6 days' +%F)" '$0<=upTo {print}' | xargs rm -r
慢动作:
printf '%s\n' $d/*/
生成一个流,其中每一行都是 的子目录/path/to/deleted
(此行包含完整路径/path/to/deleted/2020-04-12
:)这被传递
awk
给-v upTo="$d/$(date -d '-6 days' +%F)"
:创建一个upTo
变量,它是最近要删除的目录(带有完整路径/path/to/deleted/2020-04-12
:)'$0<=upTo {print}'
是一个awk
程序,仅打印出按字典顺序小于或等于内容的输入行upTo
,因此这会过滤掉中断日期之后的目录。
xargs rm -r
适用rm -r
于来自标准输入的所有行(即未过滤掉的目录)
这段代码的优点是没有 shell 循环,并且rm
可能只对所有目录调用一次。
如果您cd /path/to/deleted
首先,代码会更简单一些(您不再需要该$d
变量)。
printf '%s\n' */ | awk -v upTo="$(date -d '-6 days' +%F)" '$0<=upTo {print}' | xargs rm -r