我想记录mysql服务器每分钟的slave延迟,所以准备了一个简单的脚本。
#!/bin/bash
echo "`date` : `mysql -uroot -pXXXXXX -e"show slave status\G" | grep -i seconds_behind_master | awk '{$1=$1};1'`"
示例输出如下:
Wed Jul 1 11:40:17 +0530 2020 : Seconds_Behind_Master: NULL
Wed Jul 1 11:41:17 +0530 2020 : Seconds_Behind_Master: NULL
Thu Jul 2 11:42:17 +0530 2020 : Seconds_Behind_Master: 0
Fri Jul 3 11:40:17 +0530 2020 : Seconds_Behind_Master: 1
.
.
.
Fri Jul 31 4:40:17 +0530 2020 : Seconds_Behind_Master: 10
现在,在同一个脚本中,有没有一种方法可以包含一个清除逻辑,以根据日期字段清除 30 天以上的记录。我使用的是centos 8
提前致谢。
答案1
cutoff=$( date -d "30 days ago" "+%s" )
while read -r line ; do
timestamp=$( date -d"$( echo $line | cut -d: -f1,2,3 )" "+%s" )
if [ $timestamp -gt $cutoff ] ; then
printf -- '%s\n' "$line"
fi
done
像这样使用
$ purge.sh < data > newdata
解释:
首先获取 30 天前的纪元格式的时间戳。然后解析输入中的时间戳并以纪元格式打印它们。然后将解析后的时间戳与 30 天前的时间戳进行比较,并仅打印较新的行。
纪元格式是一个数字中的整个时间戳。该数字表示自 1970 年 1 月 1 日以来经过的秒数。这个日期没什么特别的,只是大家都同意的约定。通常是整数,但如果需要比秒更高的精度,则可以有小数部分。事实上,它只是一个数字,因此很容易进行时间比较。
有关 epoch 的更多信息,请参阅此处:https://en.wikipedia.org/wiki/Unix_time
一些细节
date -d "30 days ago" "+%s"
date
很酷,因为它可以解析人类可读的表达式。
the"+%s"
是日期的参数,以便它输出纪元格式。
cut -d: -f1,2,3
该cut
命令使用冒号作为分隔符从输入中删除前三列。这是必要的,因为您使用的时间格式包含空格和冒号,并且您重复使用冒号作为列分隔符。当使用更好的日期时间格式时,这可以大大简化。稍后会详细介绍。
[ $timestamp -gt $cutoff ]
这是 bash 所说的时间戳大于截止值
printf -- '%s\n' "$line"
这只是一种复杂但有力的表达方式echo $line
关于更好的时间格式
为了让您的生活(以及您同事的生活)更轻松,我建议您使用 iso 格式编写时间戳
date -Iseconds
seconds
您想要的精度高达 的方法seconds
。这通常就足够了。
比较
$ date -Iseconds
2022-05-04T21:30:23+02:00
$ date
Mi 4. Mai 21:30:24 CEST 2022
简而言之,优点是:它没有空格,因此对于大多数文本解析工具来说它是一个“单词”。它很容易排序。它仍然是人类可读的。它没有与区域设置相关的字符串(日期和月份的名称)。
如果您使用 iso 格式编写时间戳,则清除代码可以简化为这样
while read -r isotimestamp rest ; do
timestamp=$( date -d"$isotimestamp" "+%s" )
if [ $timestamp -gt $cutoff ] ; then
printf -- '%s %s\n' "$isotimestamp" "$rest"
fi
done
cut
现在我们可以使用read
将第一个“单词”与行的其余部分分开的方法来代替 extra 。
另一种方法
只保留文件的最后 X 行会更容易、更快。例如,如果您的系统每天最多生成两行,则只需保留最后 60 行。
tail -n 60 data > newdata
当然,只有当您每天的线路数量大致相同时,这才有效。如果您有时每天有超过 9000 条线,有时只有两条线,那么这种方法将不起作用。