AWK:将时间戳转换为纪元;第一条记录总是 returns -1
AWK: convert timestamp to epoch; first record always returns -1
我有一个包含时间戳和里程表读数的输入文件,如下所示:
2017-09-16 18:14:00,80465
2017-09-19 18:23:00,80898
2017-09-21 08:05:00,81253
2017-09-27 18:20:00,82155
2017-10-03 18:36:00,82902
2017-10-09 18:33:00,83699
...并想添加转换为纪元的时间戳,代码如下:
BEGIN {}
{
# change timestamp to epoch (without TZ correction)
epoch_returned = timestamp_to_epoch()
printf("%s,%s\n", [=12=], epoch_returned)
}
function timestamp_to_epoch(timestamp_in) {
FPAT = "[0-9][0-9]"
epoch_out = mktime(" "" "" "" "" ")
return epoch_out
}
输出结果如下:
2017-09-16 18:14:00,80465,-1
2017-09-19 18:23:00,80898,1505809380
2017-09-21 08:05:00,81253,1505945100
2017-09-27 18:20:00,82155,1506500400
2017-10-03 18:36:00,82902,1507019760
2017-10-09 18:33:00,83699,1507537980
第一行总是returns-1。
我已经删除了输入文件中的第一行,(然后)第一行仍然是 returns -1。
我在输入中只留下一行。还有returns-1.
如果我在输入文件中输入一个空行,它 returns -1,而所有其他人都按预期添加纪元。
这个我看了好久,还是想不通。
我在Linux Mint 20.1 Cinnamon 4.8.6
上使用GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
。
感谢任何提示。
将 FPAT 行移到 BEGIN 块中。当您第一次调用该函数时,awk 已经使用默认 FS 将行拆分为字段。
并且您直接在函数中使用编号字段,因此传递参数没有意义。
如果您想使用 FPAT
将您的输入拆分为字段,那么您将在错误的地方使用它,它必须在 BEGIN 部分,但那不是您想要的重新尝试这样做,您的数据是 ,
分隔的,您只是想将时间戳分隔成 2 位数的段。为此,您将使用 patsplit()
而不是 FPAT
(两者都仅限 gawk,就像 mktime()
):
$ cat tst.awk
BEGIN { FS=OFS="," }
{
# change timestamp to epoch (without TZ correction)
epoch_returned = timestamp_to_epoch()
print [=10=], epoch_returned
}
function timestamp_to_epoch(timestamp_in, t, epoch_out) {
patsplit(timestamp_in,t,/[0-9][0-9]/)
epoch_out = mktime(t[1] t[2] " " t[3] " " t[4] " " t[5] " " t[6] " " t[7])
return epoch_out
}
$ awk -f tst.awk file
2017-09-16 18:14:00,80465,1505603640
2017-09-19 18:23:00,80898,1505863380
2017-09-21 08:05:00,81253,1505999100
2017-09-27 18:20:00,82155,1506554400
2017-10-03 18:36:00,82902,1507073760
2017-10-09 18:33:00,83699,1507591980
但我个人会使用普通的旧 split()
而不是 patsplit()
:
split(timestamp_in,t,/[- :]/)
epoch_out = mktime(t[1] " " t[2] " " t[3] " " t[4] " " t[5] " " t[6])
我有一个包含时间戳和里程表读数的输入文件,如下所示:
2017-09-16 18:14:00,80465
2017-09-19 18:23:00,80898
2017-09-21 08:05:00,81253
2017-09-27 18:20:00,82155
2017-10-03 18:36:00,82902
2017-10-09 18:33:00,83699
...并想添加转换为纪元的时间戳,代码如下:
BEGIN {}
{
# change timestamp to epoch (without TZ correction)
epoch_returned = timestamp_to_epoch()
printf("%s,%s\n", [=12=], epoch_returned)
}
function timestamp_to_epoch(timestamp_in) {
FPAT = "[0-9][0-9]"
epoch_out = mktime(" "" "" "" "" ")
return epoch_out
}
输出结果如下:
2017-09-16 18:14:00,80465,-1
2017-09-19 18:23:00,80898,1505809380
2017-09-21 08:05:00,81253,1505945100
2017-09-27 18:20:00,82155,1506500400
2017-10-03 18:36:00,82902,1507019760
2017-10-09 18:33:00,83699,1507537980
第一行总是returns-1。 我已经删除了输入文件中的第一行,(然后)第一行仍然是 returns -1。 我在输入中只留下一行。还有returns-1.
如果我在输入文件中输入一个空行,它 returns -1,而所有其他人都按预期添加纪元。
这个我看了好久,还是想不通。
我在Linux Mint 20.1 Cinnamon 4.8.6
上使用GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
。
感谢任何提示。
将 FPAT 行移到 BEGIN 块中。当您第一次调用该函数时,awk 已经使用默认 FS 将行拆分为字段。
并且您直接在函数中使用编号字段,因此传递参数没有意义。
如果您想使用 FPAT
将您的输入拆分为字段,那么您将在错误的地方使用它,它必须在 BEGIN 部分,但那不是您想要的重新尝试这样做,您的数据是 ,
分隔的,您只是想将时间戳分隔成 2 位数的段。为此,您将使用 patsplit()
而不是 FPAT
(两者都仅限 gawk,就像 mktime()
):
$ cat tst.awk
BEGIN { FS=OFS="," }
{
# change timestamp to epoch (without TZ correction)
epoch_returned = timestamp_to_epoch()
print [=10=], epoch_returned
}
function timestamp_to_epoch(timestamp_in, t, epoch_out) {
patsplit(timestamp_in,t,/[0-9][0-9]/)
epoch_out = mktime(t[1] t[2] " " t[3] " " t[4] " " t[5] " " t[6] " " t[7])
return epoch_out
}
$ awk -f tst.awk file
2017-09-16 18:14:00,80465,1505603640
2017-09-19 18:23:00,80898,1505863380
2017-09-21 08:05:00,81253,1505999100
2017-09-27 18:20:00,82155,1506554400
2017-10-03 18:36:00,82902,1507073760
2017-10-09 18:33:00,83699,1507591980
但我个人会使用普通的旧 split()
而不是 patsplit()
:
split(timestamp_in,t,/[- :]/)
epoch_out = mktime(t[1] " " t[2] " " t[3] " " t[4] " " t[5] " " t[6])