2009-12-25 139 views
33

我想在awk脚本中运行system命令并将其输出存储在变量中。我一直在试图做到这一点,但命令的输出总是进入shell,我无法捕获它。任何想法如何做到这一点?将系统命令的输出分配给变量

实施例:

$ date | awk --field-separator=! {$1 = system("strip $1"); /*more processing*/} 

应该调用strip系统命令和,而不是发送输出到壳,应该分配更多的处理中的输出回$1。现在是Rignt,它将输出发送到shell并将命令的retcode分配给$1

+1

尼特:输出不会壳,这将在终端/安慰。 shell不会读取其子项的任何输出 - 它们只是共享与同一个tty关联的文件描述符。 – 2009-12-25 16:54:19

回答

23

想通了。

我们使用awk的Two-way I/O

{ 
    "strip $1" |& getline $1 
} 

通过$ 1条和函数getline需要输出带回到1 $

+1

如果您需要多次调用相同的命令,我们必须关闭命令(http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_26.html#SEC29) – mcoolive 2014-08-13 08:20:48

49

注:协进程是GNU的awk具体。 反正另一种选择是使用函数getline

cmd = "strip "$1 
while ((cmd | getline result) > 0) { 
    print result 
} 
close(cmd) 
+0

谢谢。这样,我可以从我的答案中删除&。看起来更酷。但是我只写在Linux中使用,所以不可用的gawk不应该成为问题? – Sahas 2009-12-25 10:43:40

+0

是的,不应该是一个问题。仍然应该检查文档并查看coprocess是否仅在特定版本的gawk中可用。我不记得我的头顶 – ghostdog74 2009-12-25 10:45:48

+0

从版本3.1。 RedHat有3.1.5。无论如何,我会用你的建议,除非我想发送一些命令的标准输入,在这种情况下coprocess是有帮助的。 – Sahas 2009-12-25 10:47:51

5
gawk '{dt=substr($4,2,11); gsub(/\//," ",dt); "date -d \""dt"\" +%s"|getline ts; print ts}' 
+13

如果你发布的答案,你应该解释不同的部分(你做了什么,为什么它的作品)。以便其他人可以从你的答案中学习。对于一些人来说,这条线会自我解释。但对于其他人来说,很难遵循你所做的事。 – 2013-06-07 14:05:08

16

要运行awk系统命令,你可以使用system()cmd | getline

我喜欢cmd | getline,因为它可以让你捕捉值到一个变量:

$ awk 'BEGIN {"date" | getline mydate; close("date"); print "returns", mydate}' 
returns Thu Jul 28 10:16:55 CEST 2016 

更一般地,你可以在命令到一个变量:

awk 'BEGIN { 
     cmd = "date -j -f %s" 
     cmd | getline mydate 
     close(cmd) 
    }' 

注意它是重要的使用close()可防止出现“打开太多文件”错误(如果您有多个结果)(感谢mateuscb在注释中指出了这一点)。


使用system(),命令输出将自动打印,您可以看看的价值是其返回代码:

$ awk 'BEGIN {d=system("date"); print "returns", d}' 
Thu Jul 28 10:16:12 CEST 2016 
returns 0 
$ awk 'BEGIN {d=system("ls -l asdfasdfasd"); print "returns", d}' 
ls: cannot access asdfasdfasd: No such file or directory 
returns 2 
+2

用于添加'close()'的+1,如果不添加,并且有多个结果,则可能会导致“打开太多文件”。如果你有更长的命令,你可以执行'cmd =“date -j -f%s”; cmd | getline mydate;关闭(cmd)' – mateuscb 2016-10-19 22:12:49

+1

@mateuscb非常感谢您的反馈。我更新了问题以包含您的有用评论。 – fedorqui 2016-10-20 06:48:45

+1

感谢您提醒close()命令。它有很多帮助。如果不放置close(),我有时会得到多个结果的错误日期结果。随着关闭()。我的多个日期结果全部正确显示。 – csu007 2017-01-13 03:17:26