2013-12-17 86 views
36

我想从awk中为文件的每一行运行一个shell命令,而shell命令需要一个输入参数。我试图使用system(),但它不承认输入参数。如何将awk中的变量传递给shell命令?

该文件的每一行都是一个文件的地址,我想运行一个命令来处理该文件。所以,对于一个简单的例子,我想为每一行使用'wc'命令并将$1传递给wc。

awk '{system("wc $1")}' myfile 
+0

首先在SO中搜索,已经有100个解决方案。 – BMW

+2

你为什么认为awk是这个工作的正确工具?看起来像'xargs'或者简单的shell'while read line' loop会更好更容易。 –

+1

另一方面:为什么您认为wc是这份工作的正确工具?看起来awk内置变量和函数会更好更容易? –

回答

49

你就近了。你必须串联使用awk变量的命令行:

awk '{system("wc "$1)}' myfile 
+0

谢谢,这工作!但还有一个问题呢?我们可以将输出分配给一个新变量吗? –

+0

是的,我们可以。 '{newVar = system(...)}'@VahidMir – Kent

+5

这是这项工作的错误语法,它是system()的错误应用程序,打印不会做你认为它会做的事,也不会做你不能做的事将system()调用的输出分配给awk变量,您在注释中发布的内容将system()的返回代码分配给一个变量。时间喝点咖啡@Kent! –

34

你不能抢一个awk system()调用的输出,你只能得到退出状态。使用getline/pipegetline/variable/pipe结构

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

+1为获得shell命令输出的正确方式,但通常创建变量的语法是'cmd =“your_command \”“$ 1”“\”'所以在执行cmd时引用了参数,您需要测试getline大于零的结果,否则如果失败,您将陷入无限循环。 –

+1

+1。 OP,如果您需要将输出存储在var中,请接受此答案。我的var是不正确的。 – Kent

2

FYI这里是如何用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 for ENDFILE。使用其他awk将值存储在数组中并在END部分中循环打印。

0

或者使用管道|如在bash然后retrive与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}' 

该行将打印从您的服务器的所有被取缔的IP地址与原籍沿(国)使用geoip-bin软件包。

一个班轮的最后一部分是影响我们的人:

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,我写的一篇文章。

相关问题