将系统命令的输出分配给变量

Sah*_*has 47 awk pipe

我想system在awk脚本中运行该命令并将其输出存储在变量中.我一直试图这样做,但命令的输出总是进入shell而我无法捕获它.关于如何做到这一点的任何想法?

例:

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

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

gho*_*g74 56

注意:Coprocess是特定于GNU awk的.无论如何另一种选择是使用getline

cmd = "strip "$1
while ( ( cmd | getline result ) > 0 ) {
  print  result
} 
close(cmd)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您在上面的代码上有一个 for 循环,那么 `close(cmd)` 是必要的,因为我发现它是在 `1018` 次迭代后 `awk` 爆发的困难方式(这可能取决于你的系统) (2认同)

fed*_*qui 29

要在中运行系统命令,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
Run Code Online (Sandbox Code Playgroud)

更一般地说,您可以将命令设置为变量:

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

请注意,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
Run Code Online (Sandbox Code Playgroud)

  • 添加`close()`的+1,如果你不添加它,并且有多个结果,你可能会"生成太多的打开文件".如果你有一个更长的命令,你可以做`cmd ="date -j -f%s"; cmd | getline mydate; 接近(CMD)` (4认同)
  • 感谢您提醒 close() 命令。它有很大帮助。如果不放置 close(),我有时会得到多个结果的错误日期结果。随着关闭()。我的多个日期结果都正确显示。 (2认同)
  • 当我做一个| cmd |时,`close(cmd)`对我至关重要。getline var在“ awk”内部函数中被调用了几次。第二次调用它并触发了getline时,不再填充var (2认同)

Sah*_*has 28

想通了.

我们使用awk的双向I/O.

{
  "strip $1" |& getline $1
}
Run Code Online (Sandbox Code Playgroud)

将$ 1传递给strip,getline将条带的输出返回到$ 1

  • 这不是awk而是gawk特定的(gnu awk):“使用gawk,可以打开通往另一个进程的双向管道” (3认同)
  • 如果您需要多次调用同一命令,则必须关闭该命令(http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_26.html#SEC29) (2认同)

小智 6

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

  • 如果你发布答案,你应该解释不同的部分(你做了什么以及它为什么起作用).这样其他人就可以从你的答案中学习.对于某些人来说,这条线将是自我解释.但对于其他人来说,很难完全遵循你所做的. (15认同)

Dmi*_*try 5

当您需要处理 grep 输出时,可以使用它:

echo "some/path/exex.c:some text" | awk -F: '{ "basename "$1"" |& getline $1; print $1 " ==> " $2}'
Run Code Online (Sandbox Code Playgroud)

选项-F:告诉 awk 用作:字段分隔符

"basename "$1""basename在第一个字段上执行 shell 命令

|& getline $1读取子流中前一个 shell 命令的输出

output:
exex.c ==> some text
Run Code Online (Sandbox Code Playgroud)