如何在awk脚本中使用shell变量? [英] How do I use shell variables in an awk script?
问题描述
我发现了一些将外部shell变量传递给awk
脚本的方法,但是我对'
和"
感到困惑.
I found some ways to pass external shell variables to an awk
script, but I'm confused about '
and "
.
首先,我尝试使用shell脚本:
First, I tried with a shell script:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
然后尝试awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
为什么有区别?
最后我尝试了这个:
$ awk 'BEGIN{print " '$v' "}'
$ 123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1: ^ unexpected newline or end of string
对此我感到困惑.
推荐答案
将shell变量放入
awk
可以通过几种方式完成.有些比其他更好.这应该涵盖其中的大多数.如果您有任何评论,请在下面离开. v1.5
Getting shell variables into
awk
may be done in several ways. Some are better than others. This should cover most of them. If you have a comment, please leave below. v1.5
使用-v
(最好的方法,最便于携带)
使用-v
选项:(请在-v
之后使用空格,否则它将不太便于使用.例如,awk -v var=
而不是awk -vvar=
)
Using -v
(The best way, most portable)
Use the -v
option: (P.S. use a space after -v
or it will be less portable. E.g., awk -v var=
not awk -vvar=
)
variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
这应该与大多数awk
兼容,并且该变量在BEGIN
块中也可用:
This should be compatible with most awk
, and the variable is available in the BEGIN
block as well:
如果您有多个变量:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
警告.正如Ed Morton所写,转义序列将被解释,因此\t
成为真实的tab
,而不是\t
,如果这是您要搜索的内容.可以通过使用ENVIRON[]
或通过ARGV[]
Warning. As Ed Morton writes, escape sequences will be interpreted so \t
becomes a real tab
and not \t
if that is what you search for. Can be solved by using ENVIRON[]
or access it via ARGV[]
PS 如果您喜欢三个竖线作为分隔符|||
,则无法将其转义,因此请使用-F"[|][|][|]"
PS If you like three vertical bar as separator |||
, it can't be escaped, so use -F"[|][|][|]"
从程序/函数客栈到
awk
(此处使用日期)获取数据的示例
Example on getting data from a program/function inn to
awk
(here date is used)
awk -v time="$(date +"%F %H:%M" -d '-1 minute')" 'BEGIN {print time}'
代码段后变量
在这里,我们在awk
代码之后得到变量.只要您不需要BEGIN
块中的变量,此方法就可以正常工作:
Variable after code block
Here we get the variable after the awk
code. This will work fine as long as you do not need the variable in the BEGIN
block:
variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
- 添加多个变量:
- 通过这种方式,我们还可以为每个文件设置不同的字段分隔符
FS
. - 代码块之后的变量不适用于
BEGIN
块:
awk '{print a,b,$0}' a="$var1" b="$var2" file
awk 'some code' FS=',' file1.txt FS=';' file2.ext
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
还可以使用此处字符串从支持该功能的shell中将变量添加到awk
他们(包括Bash):
Variable can also be added to awk
using a here-string from shells that support them (including Bash):
awk '{print $0}' <<< "$variable"
test
与以下相同:
printf '%s' "$variable" | awk '{print $0}'
P.S.这会将变量视为文件输入.
P.S. this treats the variable as a file input.
TrueY写道,您可以使用ENVIRON
打印环境变量.
在运行AWK之前设置变量,您可以像这样将其打印出来:
As TrueY writes, you can use the ENVIRON
to print Environment Variables.
Setting a variable before running AWK, you can print it out like this:
X=MyVar
awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
输入
正如史蒂文·潘尼(Steven Penny)所写,您可以使用ARGV
将数据放入awk:
ARGV
input
As Steven Penny writes, you can use ARGV
to get the data into awk:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
要将数据获取到代码本身中,而不仅仅是BEGIN:
To get the data into the code itself, not just the BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
代码中的变量:小心使用
您可以在awk
代码中使用变量,但是它很杂乱且难以阅读,正如Charles Duffy
所指出的,此版本也可能是代码注入的受害者.如果有人在变量中添加了不良内容,它将作为awk
代码的一部分执行.
Variable within the code: USE WITH CAUTION
You can use a variable within the awk
code, but it's messy and hard to read, and as Charles Duffy
points out, this version may also be a victim of code injection. If someone adds bad stuff to the variable, it will be executed as part of the awk
code.
这是通过在代码中提取变量来实现的,因此它成为其中的一部分.
This works by extracting the variable within the code, so it becomes a part of it.
如果您要使awk
随变量的使用而动态变化,则可以这样做,但是请勿将其用于普通变量.
If you want to make an awk
that changes dynamically with use of variables, you can do it this way, but DO NOT use it for normal variables.
variable="line one\nline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
以下是代码注入的示例:
Here is an example of code injection:
variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
您可以通过这种方式向awk
添加很多命令.甚至使用无效命令使其崩溃.
You can add lots of commands to awk
this way. Even make it crash with non valid commands.
双引号变量总是很好的"$variable"
如果没有,则将多行添加为长单行.
It's always good to double quote variable "$variable"
If not, multiple lines will be added as a long single line.
示例:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
没有双引号的其他错误:
Other errors you can get without double quote:
variable="line one\nline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ syntax error
用单引号括起来,它不会扩展变量的值:
And with single quote, it does not expand the value of the variable:
awk -v var='$variable' 'BEGIN {print var}'
$variable
有关AWK和变量的更多信息
这篇关于如何在awk脚本中使用shell变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!