在 bash 中将两个时间戳列表相互减去
subtracting two lists of timestamps from each other in bash
我有一个脚本可以检查我的日志以了解应用程序何时关闭和备份(应用程序的可用性)的时间戳。
我想找出时间戳列表之间的差异,然后将所有这些差异加起来,这样我就知道应用程序已关闭的总时间。所以 downtime.txt 文件有一个这样的列表:
04:55:51
05:41:51
uptime.txt 有一个类似格式的列表:
04:56:59
05:42:21
如果我不需要将时间戳转换为用于算术的数字,我认为我可以
粘贴 downtime.txt uptime.txt | awk '{print $1 - $2}'>timedown.txt
或类似的东西。我如何读取时间戳,将其转换为数字,从两个文件中减去匹配的行,然后将这些行的所有总和相加?
您可以使用date
命令来转换时间戳。不幸的是,您的时间戳没有日期,不确定午夜过后会发生什么,但假设您没有这个问题,您可以选择固定日期“1970 年 1 月 1 日 UTC”进行计算.
这是您的代码:
paste downtime.txt uptime.txt | while read d u; do echo $(( $(date -d "01-Jan-1970 UTC $u" +%s) - $(date -d "01-Jan-1970 UTC $d" +%s) )); done
说明:date
命令将时间戳转换为秒。 -d
选项表示在下一个日期而不是 "now" 采取行动。所以我们使用您的输入文件给它一个日期,假设指定的时间是从午夜开始。由于 date
计算自 1970 年 1 月 1 日 UTC 00:00:00 以来的秒数,我们添加该日期以简化结果。 +%s
参数的意思是,告诉我自 01-Jan-1970 以来有多少秒。这是转换的来源。由于我们指定了 -d
,它使用您指定的时间戳而不是 "now"。所以 $(date -d "01-Jan-1970 UTC $u" +%s)
的值是自午夜以来正常运行时间的秒数。然后我们使用 $(( ... ))
从正常运行时间秒数中减去停机时间秒数,得到两个时间戳之间的秒数。 (如果您的 bash 没有该功能,您可以使用 $(expr $(date -d "01-Jan-1970 UTC $u" +%s) - $(date -d "01-Jan-1970 UTC $d" +%s) )
代替)。
更新:我应该完成这项工作。要累加和统计总时间,可以加上| awk '{total=total+} END {print $total}'
。要将其转换回小时和分钟,请再次使用 date
;使用 -u
选项来防止转换为当地时间,使用 @
的 -d
选项来指定秒数(我们再次使用 01-Jan-1970 作为基础,这就是 @
表示), +%T
转换为小时和分钟,但如果超过 24 小时,您将失去额外的天数。
date -u -d @$(paste downtime.txt uptime.txt | while read d u; do echo $(( $(date -d "01-Jan-1970 UTC $u" +%s) - $(date -d "01-Jan-1970 UTC $d" +%s) )); done | awk '{total=total+} END {print total}') +%T
我有一个脚本可以检查我的日志以了解应用程序何时关闭和备份(应用程序的可用性)的时间戳。
我想找出时间戳列表之间的差异,然后将所有这些差异加起来,这样我就知道应用程序已关闭的总时间。所以 downtime.txt 文件有一个这样的列表:
04:55:51
05:41:51
uptime.txt 有一个类似格式的列表:
04:56:59
05:42:21
如果我不需要将时间戳转换为用于算术的数字,我认为我可以
粘贴 downtime.txt uptime.txt | awk '{print $1 - $2}'>timedown.txt
或类似的东西。我如何读取时间戳,将其转换为数字,从两个文件中减去匹配的行,然后将这些行的所有总和相加?
您可以使用date
命令来转换时间戳。不幸的是,您的时间戳没有日期,不确定午夜过后会发生什么,但假设您没有这个问题,您可以选择固定日期“1970 年 1 月 1 日 UTC”进行计算.
这是您的代码:
paste downtime.txt uptime.txt | while read d u; do echo $(( $(date -d "01-Jan-1970 UTC $u" +%s) - $(date -d "01-Jan-1970 UTC $d" +%s) )); done
说明:date
命令将时间戳转换为秒。 -d
选项表示在下一个日期而不是 "now" 采取行动。所以我们使用您的输入文件给它一个日期,假设指定的时间是从午夜开始。由于 date
计算自 1970 年 1 月 1 日 UTC 00:00:00 以来的秒数,我们添加该日期以简化结果。 +%s
参数的意思是,告诉我自 01-Jan-1970 以来有多少秒。这是转换的来源。由于我们指定了 -d
,它使用您指定的时间戳而不是 "now"。所以 $(date -d "01-Jan-1970 UTC $u" +%s)
的值是自午夜以来正常运行时间的秒数。然后我们使用 $(( ... ))
从正常运行时间秒数中减去停机时间秒数,得到两个时间戳之间的秒数。 (如果您的 bash 没有该功能,您可以使用 $(expr $(date -d "01-Jan-1970 UTC $u" +%s) - $(date -d "01-Jan-1970 UTC $d" +%s) )
代替)。
更新:我应该完成这项工作。要累加和统计总时间,可以加上| awk '{total=total+} END {print $total}'
。要将其转换回小时和分钟,请再次使用 date
;使用 -u
选项来防止转换为当地时间,使用 @
的 -d
选项来指定秒数(我们再次使用 01-Jan-1970 作为基础,这就是 @
表示), +%T
转换为小时和分钟,但如果超过 24 小时,您将失去额外的天数。
date -u -d @$(paste downtime.txt uptime.txt | while read d u; do echo $(( $(date -d "01-Jan-1970 UTC $u" +%s) - $(date -d "01-Jan-1970 UTC $d" +%s) )); done | awk '{total=total+} END {print total}') +%T