如何将变量从 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从入门到入土(23)awk内置变量ARGCARGC--命令行参数传递