awk '{ TEMPVAR="/usr/bin"; printf("%s", system("ls $TEMPVAR")); }' empty
在此示例中,我尝试将变量引入调用TEMPVAR
中system
。我该怎么做?
我的目标是:我试图date -d $0 +%s
在system
文件每一行发生的调用中使用。但是,我正在努力解决如何将该$0
值放入系统调用中的问题。
答案1
awk
可以使用ENVIRON
特殊数组访问环境变量。但是,虽然您可以为该数组的元素赋值,但它不会在awk
's system
、| getline
或执行的命令的环境中传递print |
。该数组仅ENVIRON
用于awk
得到它传递的环境变量的值。
您可以执行: ,但请注意,传递给's (或或)system("ls " var)
的字符串实际上是作为参数传递给 的,因此它被解释为 shell 代码。awk
system()
print |
| getline
sh -c
例如,如果awk
var
变量包含foo;rm -rf /
,则不会告诉ls
列出调用的文件"foo;rm -rf /"
,而是列出调用的文件foo
,然后rm
运行命令。
var
因此,您可能需要转义该变量中 shell 特有的所有字符。
例如,这可以通过以下方式完成:
awk '
function escape(s) {
gsub(/'\''/, "&\\\\&&", s)
return "'\''" s "'\''"
}
{
cmd = "date -d " escape($0) " +%s"
cmd | getline seconds
close(cmd)
print seconds
}'
虽然这意味着每行运行一个 shell 和一个date
命令,但您也可以使用 shell 本身来读取文件:
while IFS= read <&3 -r line; do
date -d "$line" +%s
done 3< the-file
答案2
如果您将 Awk 变量传递给系统,你需要 shell 引用它:
function quote(str, d, m, x, y, z) {
d = "\47"; m = split(str, x, d)
for (y in x) z = z d x[y] d (y < m ? "\\" d : "")
return z
}
例子:
system(sprintf("date -d %s +%%s", quote($0)))