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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将awk中一个变量的值传递给shell中的变量相关的知识,希望对你有一定的参考价值。

awk中使用shell中的变量
一: "\'$var\'"
这种写法大家无需改变用\'括起awk程序的习惯,是老外常用的写法.如:
var="test"
awk \'BEGINprint "\'$var\'"\'
这种写法其实际是双括号变为单括号的常量,传递给了awk.
如果var中含空格,为了shell不把空格作为分格符,便应该如下使用:
var="this is a test"
awk \'BEGINprint "\'"$var"\'"\'
二: \'"$var"\'
这种写法与上一种类似.如果变量含空格,则变为\'""$var""\'较为可靠.
三: export变量,使用ENVIRON["var"]形式,获取环境变量的值
例如:
var="this is a test"; export var;
awk \'BEGINprint ENVIRON["var"]\'
四:可以使用awk的-v选项 (如果变量个数不多,个人偏向于这种写法)
例如:
var="this is a test"
awk -v awk_var="$var" \'BEGIN print awk_var\'
这样便把系统变量var传递给了awk变量awk_var.

awk向shell变量传递值
“由awk向shell传递变量”,其思想无非是用awk(sed/perl等也是一样)输出若干条shell命令,然后再用shell去执行这些命令。
eval $(awk \'BEGINprint "var1=\'str1\';var2=\'str2\'"\')
或者eval $(awk \'printf("var1=%s; var2=%s; var3=%s;",$1,$2,$3)\' abc.txt)
之后可以在当前shell中使用var1,var2等变量了。
echo "var1=$var1 ----- var2=$var2"
参考技术A 一:"'$var'"这种写法大家无需改变用'括起awk程序的习惯,是老外常用的写法.如:var="test"awk'BEGINprint "'$var'"'这种写法其实就是把一对单引号分成了两段单引号,中间的shell变量直接按照shell变量的引用方式即可,但是如果var中含空格,为了shell不把空格作为分格符,便应该如下使用:var="thisis a test"awk'BEGINprint "'"$var"'"' (也就是在shell变量的两边加上一对双引号即可)二:export变量,使用ENVIRON["var"]形式, (ENVIRON为awk中的内置环境变量数组)如: var="thisis a test";export $varawk'BEGINprint ENVIRON["var"]'三:当然也可以使用-v选项如:var="thisis a test"awk –vnvar="$var" 'BEGINprintnvar'这样便把系统变量定义成了awk变量. 如果在awk是这种格式的话 awk 'script'filename 也可以这样引用shell变量awk'script' awkvar="shellvar" filename awk'ENDprint awkvar' awkvar="$shellvar" filename本回答被提问者和网友采纳

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

【中文标题】如何将变量从 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 命令?

怎么给bash shell当中的变量获取awk行处理后得到的值

如何在 awk 脚本中使用 shell 变量?

awk的结果怎么赋值给Shell变量

awk中使用shell中的变量

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