bash: 如何在没有 date -d 选项的情况下比较 Solaris 上的两个日期
bash: How to compare two dates on Solaris without date -d option
我正在尝试将从日志文件的行输入的日期与昨天的日期进行比较,如果差异超过一天,那么它会从日志文件中打印该行。
日志文件:
$more ActiveX2Alarms.log
2016-09-30 01:40:14 MET;faultManager:network@ET_AO_L_0165_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ET_AO_L_0165_abcde_44159@x2Transp-0|alarm-2632-3-698;ET_AO_L_0165_abcde;major;2632
;lte.IK4009022;3;698
2016-11-01 08:10:51 MET;faultManager:network@ER_AO_L_4283_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ER_AO_L_4283_abcde_14179@x2Transp-0|alarm-2632-3-698;ER_AO_L_4283_abcde;minor;2632;lte.IK4009022;3;698
2017-01-03 12:14:31 MET;faultManager:network@EM_AO_L_4065_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_EM_AO_L_4065_abcde_44094@x2Transp-0|alarm-2632-3-698;EM_AO_L_4065_
abcde;minor;2632;lte.IK4009022;3;698
我已经使用 cygwin 在 Windows 上创建了测试环境。
在 Cygwin 中,我已经成功 o/p.
这是我使用的初始代码:
awk -v d="$(date -d "yesterday" +'%Y-%m-%d %H:%M:%S')" ' " " < d' /cygdrive/f/Script_X2/Final/Last_Trial/ActiveX2Alarms.log
结果:
2016-09-30 01:40:14 MET;faultManager:network@ET_AO_L_0165_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ET_AO_L_0165_abcde_44159@x2Transp-0|alarm-2632-3-698;ET_AO_L_0165_abcde;major;2632
;lte.IK4009022;3;698
2016-11-01 08:10:51 MET;faultManager:network@ER_AO_L_4283_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ER_AO_L_4283_abcde_14179@x2Transp-0|alarm-2632-3-698;ER_AO_L_4283_abcde;minor;2632;lte.IK4009022;3;698
然而,当在主服务器上使用相同的命令时,我收到一个错误:
date: illegal option --d
正在搜索错误,我知道它与安装的 Solaris 软件包有关
$uname -a
SunOS xxxxxx 5.10 Generic_150400-15 sun4u sparc SUNW,SPARC-Enterprise
$date --version
date: illegal option -- version
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
$date --help
date: illegal option -- help
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
所以我使用了下面的代码来避免这个问题,但是它没有给出任何输出...所以还是有问题,请帮忙!
$awk -v YESTERDAY="`TZ=GMT+20 date +'%d-%m-%Y %H:%M:%S'`" ' " " < YESTERDAY' ActiveX2Alarms.log
awk: syntax error near line 1
awk: bailing out near line 1
$/usr/xpg4/bin/awk -v YESTERDAY="`TZ=GMT+20 date +'%d-%m-%Y %H:%M:%S'`" ' " " < YESTERDAY' ActiveX2Alarms.log
$
确认 YESTERDAY 变量赋值成功:
$YESTERDAY="`TZ=GMT+20 date +'%d-%m-%Y %H:%M:%S'`"; echo $YESTERDAY
02-01-2017 16:51:26
日志文件和 YESTERDAY
的日期格式不同,但应该一致。由于日志文件是按 Y-M-D 顺序排列的,因此使用:
awk -v YESTERDAY="`TZ=GMT+20 date +'%Y-%m-%d %H:%M:%S'`" '( " " ) < YESTERDAY' ActiveX2Alarms.log
^^^^^^^^ was %d-%m-%Y
在我的测试系统(也是 cygwin)上,这给出了与您在问题中显示的相同的两行输出。
这是因为 awk
比较的是字符串,而不是日期,所以日期必须在 Y-M-D 中才能按数字排序。 awk
不会自动将日期字符串转换为实际日期(据我所知)。我在 ( " " )
中添加了括号,以阐明您正在制作一个将与另一个字符串进行比较的字符串。
注意:虽然我认为您的 TZ=GMT+20
hack 非常酷,但 GMT+20 仅比 MET 早 19 小时,而不是 24 小时。因此,如果您在一天中的错误时间 运行 脚本,将无法正确设置 YESTERDAY
。 This answer 有一个示例,说明如何在 bash
中获取昨天的日期而不考虑时区。
如何找到昨天?
由于夏令时,24 小时前可能是今天或前天。如果您想在不使用 GNU 日期的情况下更改脚本,请使用以下技巧:
您确定昨天是 20 或 30 小时前。哪一个?嗯,最近的不是今天。
yesterday=$(printf "%s\n" "$(TZ=GMT+30 date +%Y-%m-%d)" "$(TZ=GMT+20 date +%Y-%m-%d)" |
grep -v $(date +%Y-%m-%d) | tail -1)
如果您想查看 24 小时的差异(并希望包括时间),请使用类似
的内容
yesterdaynow="${yesterday} $(date +'%H:%M:%S')"
请注意,这可能是 23 或 25 小时前,切换 DST 时。
注:
当你有 "new" bash 版本时,你可以使用其他 printf 选项,请参阅
使用它,您可以将日期转换为纪元并计算它们的差异。
我正在尝试将从日志文件的行输入的日期与昨天的日期进行比较,如果差异超过一天,那么它会从日志文件中打印该行。
日志文件:
$more ActiveX2Alarms.log
2016-09-30 01:40:14 MET;faultManager:network@ET_AO_L_0165_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ET_AO_L_0165_abcde_44159@x2Transp-0|alarm-2632-3-698;ET_AO_L_0165_abcde;major;2632
;lte.IK4009022;3;698
2016-11-01 08:10:51 MET;faultManager:network@ER_AO_L_4283_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ER_AO_L_4283_abcde_14179@x2Transp-0|alarm-2632-3-698;ER_AO_L_4283_abcde;minor;2632;lte.IK4009022;3;698
2017-01-03 12:14:31 MET;faultManager:network@EM_AO_L_4065_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_EM_AO_L_4065_abcde_44094@x2Transp-0|alarm-2632-3-698;EM_AO_L_4065_
abcde;minor;2632;lte.IK4009022;3;698
我已经使用 cygwin 在 Windows 上创建了测试环境。 在 Cygwin 中,我已经成功 o/p.
这是我使用的初始代码:
awk -v d="$(date -d "yesterday" +'%Y-%m-%d %H:%M:%S')" ' " " < d' /cygdrive/f/Script_X2/Final/Last_Trial/ActiveX2Alarms.log
结果:
2016-09-30 01:40:14 MET;faultManager:network@ET_AO_L_0165_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ET_AO_L_0165_abcde_44159@x2Transp-0|alarm-2632-3-698;ET_AO_L_0165_abcde;major;2632
;lte.IK4009022;3;698
2016-11-01 08:10:51 MET;faultManager:network@ER_AO_L_4283_abcde@eNBEquip@eNBInst@x2Grp-0@x2Access-0_424_02_ER_AO_L_4283_abcde_14179@x2Transp-0|alarm-2632-3-698;ER_AO_L_4283_abcde;minor;2632;lte.IK4009022;3;698
然而,当在主服务器上使用相同的命令时,我收到一个错误:
date: illegal option --d
正在搜索错误,我知道它与安装的 Solaris 软件包有关
$uname -a
SunOS xxxxxx 5.10 Generic_150400-15 sun4u sparc SUNW,SPARC-Enterprise
$date --version
date: illegal option -- version
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
$date --help
date: illegal option -- help
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
所以我使用了下面的代码来避免这个问题,但是它没有给出任何输出...所以还是有问题,请帮忙!
$awk -v YESTERDAY="`TZ=GMT+20 date +'%d-%m-%Y %H:%M:%S'`" ' " " < YESTERDAY' ActiveX2Alarms.log
awk: syntax error near line 1
awk: bailing out near line 1
$/usr/xpg4/bin/awk -v YESTERDAY="`TZ=GMT+20 date +'%d-%m-%Y %H:%M:%S'`" ' " " < YESTERDAY' ActiveX2Alarms.log
$
确认 YESTERDAY 变量赋值成功:
$YESTERDAY="`TZ=GMT+20 date +'%d-%m-%Y %H:%M:%S'`"; echo $YESTERDAY
02-01-2017 16:51:26
日志文件和 YESTERDAY
的日期格式不同,但应该一致。由于日志文件是按 Y-M-D 顺序排列的,因此使用:
awk -v YESTERDAY="`TZ=GMT+20 date +'%Y-%m-%d %H:%M:%S'`" '( " " ) < YESTERDAY' ActiveX2Alarms.log
^^^^^^^^ was %d-%m-%Y
在我的测试系统(也是 cygwin)上,这给出了与您在问题中显示的相同的两行输出。
这是因为 awk
比较的是字符串,而不是日期,所以日期必须在 Y-M-D 中才能按数字排序。 awk
不会自动将日期字符串转换为实际日期(据我所知)。我在 ( " " )
中添加了括号,以阐明您正在制作一个将与另一个字符串进行比较的字符串。
注意:虽然我认为您的 TZ=GMT+20
hack 非常酷,但 GMT+20 仅比 MET 早 19 小时,而不是 24 小时。因此,如果您在一天中的错误时间 运行 脚本,将无法正确设置 YESTERDAY
。 This answer 有一个示例,说明如何在 bash
中获取昨天的日期而不考虑时区。
如何找到昨天?
由于夏令时,24 小时前可能是今天或前天。如果您想在不使用 GNU 日期的情况下更改脚本,请使用以下技巧:
您确定昨天是 20 或 30 小时前。哪一个?嗯,最近的不是今天。
yesterday=$(printf "%s\n" "$(TZ=GMT+30 date +%Y-%m-%d)" "$(TZ=GMT+20 date +%Y-%m-%d)" |
grep -v $(date +%Y-%m-%d) | tail -1)
如果您想查看 24 小时的差异(并希望包括时间),请使用类似
的内容yesterdaynow="${yesterday} $(date +'%H:%M:%S')"
请注意,这可能是 23 或 25 小时前,切换 DST 时。
注:
当你有 "new" bash 版本时,你可以使用其他 printf 选项,请参阅
使用它,您可以将日期转换为纪元并计算它们的差异。