我是unix新手。我正在尝试查找多个作业的最新日志并删除最新的日志。
我可以为它写一个shell脚本吗?我尝试过使用基本命令,但它正在选择一个时间范围并可以删除日志,但它可能还删除有用的日志。
分享我发现的:
touch -t 201903281325.00 start
touch -t 201903281331.00 stop
find . -newer start \! -newer stop -type f \( -name "**" -o -name "**" \) -exec rm -f {} \;
这将删除该时间限制内的所有文件
我想做的事 :
假设作业的名称为 A、B、C 等,这些作业每天运行 5 次——例如 A_1、A_2、A_3、B_1、B_2、B_3 等。
说今天生成的运行日志
Order_created_20190611_1.log
Order_created_20190611_2.log
Order_created_20190611_3.log
Order_zip_rec_20190611_1.log
Order_zip_rec_20190611_2.log
我必须自动删除的内容:
Order_created_20190611_3.log
Order_zip_rec_20190611_2.log
我想自动查找Order_created_20190611_3.log
并Order_zip_rec_20190611_2.log
删除它们。
职位名称示例:
Order_created
-- 职位名称20190611
- 执行日期_2
(最后提到) - 是它运行的次数。_2
意味着今天的跑步是第二次。
答案1
对于诸如此类的简单文件名,您可以保证它们不会包含换行符等奇怪字符,因此解析ls
. (一般情况下不推荐这样做.)
正如您的问题中所描述的,我们假设我们正在处理与这些模式匹配的文件,其中*
当然会匹配“任何内容”:
Order_created_20190611_*.log
Order_zip_rec_20190611_*.log
此外,对于基于今天日期的文件,您可以像这样找到“最新”文件:
# Today's date in YYYYMMDD format
today="$(date +%Y%m%d)"
# Get "ls" to give us the files ordered by date modified (newest first). Pick off the first
newest="$(ls -t "Order_created_${today}_"*".log" | head -n1)"
# Show what we would delete (remove "echo" to action)
echo rm "$newest"
使用这个原则,您可以将其汇总到跨多个文件名的循环中:
today="$(date +%Y%m%d)"
for prefix in Order_created Order_zip_rec
do
newest="$(ls -t "${prefix}_${today}_"*".log" 2>/dev/null | head -n1)"
[[ -f "$newest" ]] && echo rm "$newest"
done
注意事项
- 您通常不应假设您可以解析
ls
.在这种情况下我这样做是因为你的文件名定义良好(并且没有sort
或 的GNU 扩展名find
) ls
我已经放弃了没有匹配文件的情况下的错误输出rm
同样,我仅在有文件要删除时才尝试
答案2
要删除每组作业和日期的“最后”(编号最高的“运行”)日志文件,我建议使用基于 ksh93 的解决方案,该解决方案可以跟踪每个组合看到的最高作业运行以及列表要删除的文件数:
#!/bin/ksh93
typeset -A highestjobruns=()
typeset -A deletions=()
for logfile in *_????????_*.log
do
base=${logfile%.log}
run=${base##*_}
jobdate=${base%_?}
if [ -z "${highestjobruns[$jobdate]}" ]
then
# no job runs found yet, this is it; nothing to delete yet
highestjobruns[$jobdate]=$run
else
# if this file has a higher run number, it's the new target for deletion
if [ "$run" -gt "${highestjobruns[$jobdate]}" ]
then
highestjobruns[$jobdate]=$run
deletions[$jobdate]=$logfile
fi
fi
done
printf 'Would rm: %s\n' "${deletions[@]}"
#rm -- "${deletions[@]}"
基本思想是循环遍历每个潜在的日志文件(根据口味调整通配符;我需要“任何内容”,下划线,六位数字,下划线,“任何内容”,以 结尾.log
),挑选运行编号和作业组合和日期,然后问一些问题:
- 我们是否记录过此作业和日期组合的运行情况?如果没有,请记录这一点并继续。这意味着我们不会删除单例作业运行。
- 如果我们之前看到过这种作业和日期组合的运行,那么我们正在查看的运行是否高于我们迄今为止看到的最高运行?如果是这样,记录新的运行编号并将当前文件填充为我们可能删除的文件。相同作业和日期的后续日志可能会覆盖此条目,因此我们只会针对每个作业名称和日期删除一个日志文件。
最后,我打印rm
我们要删除的文件的示例命令;如果您愿意,请将其注释掉,并取消注释实际rm
命令本身以进行删除。