如何将变量从 awk 传递到 shell 命令?

Posted

技术标签:

【中文标题】如何将变量从 awk 传递到 shell 命令?【英文标题】:How can I pass variables from awk to a shell command? 【发布时间】:2014-01-05 23:06:25 【问题描述】:

我试图在 awk 中为文件的每一行运行一个 shell 命令,而 shell 命令需要一个输入参数。我尝试使用system(),但它无法识别输入参数。

这个文件的每一行都是一个文件的地址,我想运行一个命令来处理那个文件。因此,对于一个简单的示例,我想对每一行使用“wc”命令并将$1传递给 wc。

awk 'system("wc $1")' myfile

【问题讨论】:

您为什么认为 awk 是适合这项工作的工具?似乎xargs 或简单的shell while read line 循环会更好更容易。 另一方面:为什么您认为 wc 是适合这项工作的工具?似乎 awk 内置变量和函数会更好更容易? 【参考方案1】:

你很接近。您必须将命令行与 awk 变量连接起来:

awk 'system("wc "$1)' myfile

【讨论】:

谢谢,这行得通!但还有一个问题?我们可以将输出分配给一个新变量吗? 这是这个作业的错误语法,它是 system() 的错误应用程序,打印没有按照您的想法执行,不,您不能分配系统的输出( ) 调用 awk 变量,您在评论中发布的内容将 system() 的返回代码分配给变量。是时候喝杯咖啡了@Kent! @EdMorton 是的!系统返回状态码.....我被 vimscripts 的system()...:( . cmd|getline var 应该读取输出......这个答案/评论对于变量部分不正确. system() 部分也不正确——应该是system("wc \"" $1 "\"") 传2个参数怎么处理?【参考方案2】:

您无法获取 awk system() 调用的输出,您只能获取退出状态。使用getline/pipe 或getline/variable/pipe 构造

awk '
    cmd = "your_command " $1
    while (cmd | getline line) 
        do_something_with(line) 
    
    close(cmd)
' file

【讨论】:

+1 获取shell命令输出的正确方法,但通常创建变量的语法是cmd = "your_command \"" $1 ""\",因此在执行cmd时会引用参数并且您需要测试对于 getline 的结果大于零,否则如果失败,您将陷入无限循环。 +1 。 OP,如果您需要将输出存储在 var 中,也请接受这个答案。我的 var 分配不正确。 @EdMorton 我想你的意思是cmd = "your_command \"" $1 "\"" @jaygooby 是的,我知道,很好发现。【参考方案3】:

仅供参考,这里是如何使用 awk 处理名称存储在文件中的文件(在此示例中提供类似 wc 的功能):

gawk '
NR==FNR  ARGV[ARGC++]=$0; next 
 nW+=NF; nC+=(length($0) + 1) 
ENDFILE  print FILENAME, FNR, nW, nC; nW=nC=0 
' file

以上使用 GNU awk 作为 ENDFILE。对于其他 awk,只需将值存储在数组中并在 END 部分的循环中打印。

【讨论】:

【参考方案4】:

或者在 bash 中使用管道 | 然后使用 awk 的 getline 在变量中检索输出,就像这样

 zcat /var/log/fail2ban.log* | gawk  '/.*Ban.*/  print $7;' | sort | uniq -c | sort | gawk ' "geoiplookup " $2 "| cut -f2 -d: " | getline geoip; print $2 "\t\t" $1 " " geoip'

该行将使用 geoip-bin 包从您的服务器打印所有被禁止的 IP 及其来源(国家/地区)。

那条线的最后一部分是影响我们的那部分:

gawk ' "geoiplookup " $2 "| cut -f2 -d: " | getline geoip; print $2 "\t\t" $1 " " geoip'

它只是说:运行命令"geoiplookup 182.193.192.4 | -f2 -d:"(您可能猜到$2被替换)并将该命令的结果放入geoip(| getline geoip位)。接下来,在geoip 变量中打印一些东西和任何东西。

完整的例子和结果可以在我写的一篇文章here找到。

【讨论】:

【参考方案5】:

我会建议另一种解决方案:

awk 'print $1' myfile | xargs wc

不同之处在于它使用多个参数执行一次wc。它通常有效(例如,使用 kill 命令)

【讨论】:

以上是关于如何将变量从 awk 传递到 shell 命令?的主要内容,如果未能解决你的问题,请参考以下文章

如何将awk中一个变量的值传递给shell中的变量

awk使用shell变量,shell获取awk中的变量值

awk使用shell变量,shell获取awk中的变量值

awk从入门到入土(23)awk内置变量ARGCARGC--命令行参数传递

awk从入门到入土(23)awk内置变量ARGCARGC--命令行参数传递

关于shell变量值的截取-通过分隔符-去除前后匹配到的内容