如何将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中的变量的主要内容,如果未能解决你的问题,请参考以下文章