如何在awk脚本中使用shell变量? [英] How do I use shell variables in an awk script?

查看:196
本文介绍了如何在awk脚本中使用shell变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一些将外部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

  • 添加多个变量:
  • awk '{print a,b,$0}' a="$var1" b="$var2" file

    • 通过这种方式,我们还可以为每个文件设置不同的字段分隔符FS.

    awk 'some code' FS=',' file1.txt FS=';' file2.ext

    • 代码块之后的变量不适用于BEGIN块:

    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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆