为什么所有这些都不起作用?
$ 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