根据 shell 脚本中的年龄清除文件中的行

根据 shell 脚本中的年龄清除文件中的行

我想记录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 条线,有时只有两条线,那么这种方法将不起作用。

相关内容