Reputation: 40758
Consider passing some set of arguments to a function, e.g.:
awk -vv1="Hello there" -vv2=Bye 'BEGIN {print v1,v2}'
Note that the first argument contains a space. The output is:
Hello there Bye
Now, I try to store the arguments in a variable. Consider first the case without a space in the first argument:
arg="-vv1=Hello -vv2=Bye"
awk $arg 'BEGIN {print v1,v2}'
This works fine. Now insert the space in the variable:
arg="-vv1='Hello there' -vv2=Bye"
awk $arg 'BEGIN {print v1,v2}'
which gives the error message:
awk: there'
awk: ^ invalid char ''' in expression
What is happening here?
Based on the comments so far, I would like to refine my question:
Consider the case where arg
is the output of another shell script.
For instance, assume that genArg
is a shell script that prints the string:
"-vv1='Hello there' -vv2=Bye"
to the terminal. Then arg
is collected (in a script) like
arg=$(genArg)
and next I would like to call awk
with the given arguments:
awk $arg 'BEGIN {print v1,v2}'
Upvotes: 1
Views: 2788
Reputation: 203597
In response to your updated question and comments:
$ 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"
Here's a, IMHO, better alternative:
$ 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"
If you want to use named instead of numbered variables:
$ 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"
Us the array v[] indexed by key strings as-is or map it's values to variables specifically named based on the keys strings. Either way...
Upvotes: 3
Reputation: 531185
Use an array:
arg=(-vv1="Hello there" -vv2=Bye)
awk "${arg[@]}" 'BEGIN {print v1,v2}'
Upvotes: 9
Reputation: 249153
Try this:
arg1="-vv1=Hello there"
arg2="-vv2=Bye"
awk "$arg1" "$arg2" 'BEGIN {print v1,v2}'
The idea is to make sure that awk sees exactly three string arguments: vv1, vv2, and the actual awk script text. You can do it this way with two variables, or if you really want to, you could probably also do it using a Bash array.
Upvotes: 0