具有子 shell 初始化变量的 awk

具有子 shell 初始化变量的 awk

为什么所有这些都不起作用?

$ echo "1" | awk '{ d=$(echo hi); print d }'

$ echo "1" | awk '{ print $(echo hi) }'

$ echo "1" | awk '{ d=$(date); print d }'

全部打印“1”而不是“hi”/当前日期。

怎么了?

如果我在 awk 之外执行它,它可以正常工作:

$ d=$(echo hi); echo $d; -> prints "hi"

我的最终目标是能够做这样的事情:

$ cat dates | awk ' { d=$(date --date=$1 +"%s"); print d } '

我想查看日期列表:

2021-12-26T22:24:08+00:00
2021-12-26T22:24:18+00:00
2021-12-26T22:26:12+00:00
2021-12-26T22:28:07+00:00

并显示每个日期时间的unix时间戳。

答案1

假设您使用的是 GNU date,您可以直接使用以下命令读取带有日期的文件-f

$ cat file
2021-12-26T22:24:08+00:00
2021-12-26T22:24:18+00:00
2021-12-26T22:26:12+00:00
2021-12-26T22:28:07+00:00
$ date -f file +%s
1640557448
1640557458
1640557572
1640557687
$ date -f file +%s%t%c
1640557448      Sun Dec 26 23:24:08 2021
1640557458      Sun Dec 26 23:24:18 2021
1640557572      Sun Dec 26 23:26:12 2021
1640557687      Sun Dec 26 23:28:07 2021

awk 是它自己的编程语言,您不能在awk程序中使用 shell 扩展。$(...)in 中的构造所做awk的事情与 shell 中所做的非常不同(它访问的字段的编号是括号中表达式的结果,如 中$(1+2),它与 相同$3,它是 中第三个字段的值当前记录)。

如果你有真的如果想要用于awk此目的,您可能希望使用来substr()挑选输入文件中每行上每个日期的各个部分,然后mktime()使用这些字符串创建 Unix 时间戳。该mktime()功能是非标准的,但受常见awk实现的支持(请参阅您的awk手册)。

以下将从输入中读取的时间戳解释为 UTC 时区。

BEGIN { FS = "[-T+:]" }

{
        ts = mktime(sprintf("%.4d %.2d %.2d %.2d %.2d %.2d",
                $1, $2, $3, $4, $5, $6))

        off = -60*(60*$7 + $8)
}

/-..:..$/ { off = -off }

{ print ts + off }

我不需要substr()在这里使用,因为我将时间分割到集合中的字符上-T+:,因此可以直接将时间戳的不同部分作为字段访问。

$ TZ=UTC awk -f script file
1640553848
1640553858
1640553972
1640554087

答案2

@他们的回答为您提供适合您特定需求的解决方案,因此您应该使用他的解决方案。但万一您想知道如何在内部运行命令awk并将其存储在变量中,您可以使用该getline函数来完成此操作。从手册页awk(1)

command | getline [var]
                      Run command piping the output either into $0 or var,
                      as above.

所以这里有一些你第一次尝试的例子:

$ echo "1" | awk '{ "echo hi" |getline d; print d }'
hi

$ echo "1" | awk '{ "date" | getline d; print d }'
Mon Dec 27 02:47:29 PST 2021

这是如何通过date在内部运行来获得预期的功能awk(再次强调,实际上不要使用此命令,而是使用@他们的回答,这只是为了解释):

$ cat dates | awk ' { "date --date="$1" +%s" |getline d; print d } '
1640557448
1640557458
1640557572
1640557687

相关内容