我将一些数据存储在遵循以下命名约定的文件中:
/interesting/data/filename-YYYY-MM-DD-HH-MM
我该如何查找date in file name < now - 1 month
并删除它们?
文件自创建以来可能已经发生改变,因此根据它进行搜索last modification date
并不好。
我现在正在做的是筛选在python中:
prefix = '/interesting/data/filename-'
import commands
names = commands.getoutput('ls {0}*'.format(prefix)).splitlines()
from datetime import datetime, timedelta
all_files = map(lambda name: {
'name': name,
'date': datetime.strptime(name, '{0}%Y-%m-%d-%H-%M'.format(prefix))
}, names)
month = datetime.now() - timedelta(days = 30)
to_delete = filter(lambda item: item['date'] < month, all_files)
import os
from operator import itemgetter
map(os.remove, map(itemgetter('name'), to_delete))
有没有一个(一行)bash
解决方案?
答案1
你能使用-ctime
withfind
吗?对于文件,ctime
表示文件元数据上次更改的时间(文件创建、重命名、chmod、chown、chgrp 等)。对于大多数日志文件,创建日期和 ctime 是相同的。
答案2
假设 GNU 日期和 GNU 发现你可以这样做
#!/usr/bin/env bash
prefix="/interesting/data/filename-"
ref=/tmp/ref.$$
one_month_ago=/tmp/one_month_ago.$$
results=/tmp/results.$$
# create a file whose timestamp is "one month ago"
touch "$one_month_ago" -t $(date -d "-1 month" +%Y%m%d%I%M.%S)
while read -r file ; do
# strip the prefix, leaving the suffix
datestr=$(tail -c $(( ${#file} - ${#prefix} + 1 )) <<<"$file")
# cut the date and time out of the suffix
date=$(cut -d- -f1-3 <<<"$datestr")
time=$(cut -d- -f 4- <<<"$datestr" | tr - :)
# create a reference file whose timestamp matches the string from $file
touch "$ref" -t $(date -d "$date $time" +%Y%m%d%I%M.%S)
# ask find whether the reference file is not neewer (aka "is older")
# than one month ago
find "$ref" -not -newer "$one_month_ago" > "$results" &&
# results from find?
[ -s "$results" ] &&
# then rm the corresponding file
echo rm -f -- "$file"
done < <(find -path "$prefix"'*')
# clean up
rm -f "$ref" "$one_month_ago" "$results"
但它并不是一句俏皮话。
由于这尚未经过测试并且有些危险,我在命令echo
中添加了一个前缀rm
,因此一旦您验证结果正确,就需要将其删除。
这里的一个弱点是在文件的初始选择上。-path "$prefix"'*'
假定绝对路径,否则会中断;更智能的选择可能更好,即使它是一个简单的 shell glob(即,用替换 while 循环for file in "$prefix*" ; do ... done
。我没有这样做,因为我不知道这样的 glob 扩展是否会溢出最大命令长度。