Aay*_*ain 2 shell awk text-processing date
我有一个包含以下格式记录的文件:
D20220327,S2927,977,1
D20220328,S2927,977,1
D20220329,S2927,977,1
D20220330,S2927,977,1
D20220331,S2927,977,1
D20220401,S2927,977,1
D20220402,S2927,977,1
D20220403,S2927,977,1
D20220404,S2927,977,1
Run Code Online (Sandbox Code Playgroud)
然而,在应用转换将这些时间移回过去 7 天后,它对于 3 月 28 日至 4 月 3 日的日期不起作用,但相同的代码逻辑在 3 月 27 日和 4 月 4 日运行良好。我不明白为什么这仅在一周内不起作用。这是输出
D20220320,S2927,977,1 -- correct
D20220320,S2927,977,1 -- incorrect
D20220321,S2927,977,1 -- incorrect
D20220322,S2927,977,1 -- incorrect
D20220323,S2927,977,1 -- incorrect
D20220324,S2927,977,1 -- incorrect
D20220325,S2927,977,1 -- incorrect
D20220326,S2927,977,1 -- incorrect
D20220328,S2927,977,1 -- correct
Run Code Online (Sandbox Code Playgroud)
这里使用的逻辑是:
BEGIN {
OFS = FS = ","
}
{
t = mktime(sprintf("%4d %.2d %.2d 00 00 00",
substr($1,2,4),
substr($1,6,2),
substr($1,8,2)));
$1 = substr($1,1,1) strftime("%Y%m%d", t - 7*24*60*60)
print
}
Run Code Online (Sandbox Code Playgroud)
Kus*_*nda 11
您的计算是在当地时间完成的,并且您会受到 3 月 27 日夏令时切换的影响。
要使用 UTC 时间进行计算(Unix 时间戳不是本地时间),请使用最新版本的 GNU awk,请确保将额外的参数1作为最后一个参数传递给mktime():
t = mktime(sprintf("%4d %.2d %.2d 00 00 00",
substr($1,2,4),
substr($1,6,2),
substr($1,8,2)), 1);
Run Code Online (Sandbox Code Playgroud)
awk这是GNU 版本 4.2.0+ 中提供的GNU扩展awk。
作为替代方案,您可以避免使用午夜 (UTC) 左右的时间作为一天中的参考时间:
t = mktime(sprintf("%4d %.2d %.2d 12 00 00",
substr($1,2,4),
substr($1,6,2),
substr($1,8,2)));
Run Code Online (Sandbox Code Playgroud)
这将使它能够在较旧的 GNUawk实现和任何其他awk具有所需功能的实现中工作。
另一种选择是让脚本以更改的本地时区运行:
TZ=UTC awk -f script.awk inputfile
Run Code Online (Sandbox Code Playgroud)
这会将TZ环境变量设置为UTC执行脚本,从而更改相关函数awk使用的时区。mktime()