用bash中的变量包含的空格传递参数

时间:2013-10-11 11:38:02

标签: bash awk

考虑将一些参数集传递给函数,例如:

awk -vv1="Hello there" -vv2=Bye 'BEGIN {print v1,v2}'

请注意,第一个参数包含空格。输出是:

Hello there Bye

现在,我尝试将参数存储在变量中。首先考虑第一个参数中没有空格的情况:

arg="-vv1=Hello -vv2=Bye"
awk $arg 'BEGIN {print v1,v2}'

这很好用。现在在变量中插入空格:

arg="-vv1='Hello there' -vv2=Bye"
awk $arg 'BEGIN {print v1,v2}'

给出了错误消息:

awk: there'
awk:      ^ invalid char ''' in expression

这里发生了什么?


更新

根据到目前为止的评论,我想改进我的问题: 考虑arg是另一个shell脚本的输出的情况。 例如,假设genArg是打印字符串的shell脚本:

"-vv1='Hello there' -vv2=Bye"

到终端。然后收集arg(在脚本中),如

arg=$(genArg)

接下来我想用给定的参数调用awk

awk $arg 'BEGIN {print v1,v2}'

3 个答案:

答案 0 :(得分:8)

使用数组:

arg=(-vv1="Hello there" -vv2=Bye)
awk "${arg[@]}" 'BEGIN {print v1,v2}'

答案 1 :(得分:3)

回复您更新的问题和评论:

$ cat tst.sh
function genArg() {
    printf "Hello there\n"
    printf "Bye\n"
}

IFS=$'\n' rslts=( $(genArg) )

awk -v v1="${rslts[0]}" -v v2="${rslts[1]}" 'BEGIN{
    printf "v1=\"%s\"\n", v1
    printf "v2=\"%s\"\n", v2
}'
$
$ ./tst.sh
v1="Hello there"
v2="Bye"

这是一个,恕我直言,更好的选择:

$ cat tst.sh
function genArg() {
    printf "Hello there\n"
    printf "Bye\n"
}

awk -v rslts="$(genArg)" 'BEGIN{
    split(rslts,v,/\n/)
    for (i=1;i in v;i++)
        printf "v[%d]=\"%s\"\n", i, v[i]
}'
$
$ ./tst.sh
v[1]="Hello there"
v[2]="Bye"

如果要使用命名而不是编号变量:

$ cat ./tst.sh
function genArg() {
    printf "greeting=Hello there\n"
    printf "farewell=Bye\n"
}

awk -v rslts="$(genArg)" 'BEGIN{
    split(rslts,tmp,/\n/)
    for (i=1;i in tmp;i++) {
        var = val = tmp[i]
        sub(/=[^=]+/,"",var)
        sub(/[^=]+=/,"",val)
        v[var] = val
    }

    for (var in v)
        printf "v[%s]=\"%s\"\n", var, v[var]

    greeting = v["greeting"]
    farewell = v["farewell"]

    print "greeting=\"" greeting "\""
    print "farewell=\"" farewell "\""
}'
$
$ ./tst.sh
v[greeting]="Hello there"
v[farewell]="Bye"
greeting="Hello there"
farewell="Bye"

将数组v []按键字符串索引为as-is,或将其值映射到基于键字符串专门命名的变量。无论哪种方式......

答案 2 :(得分:0)

试试这个:

arg1="-vv1=Hello there"
arg2="-vv2=Bye"
awk "$arg1" "$arg2" 'BEGIN {print v1,v2}'

这个想法是确保awk正好看到三个字符串参数:vv1,vv2和实际的awk脚本文本。你可以用两个变量这样做,或者如果你真的想,你也可以使用Bash数组来做。