Reputation: 2632
Is there a way in Bash (without calling a 2nd script) to parse variables as if they were command line arguments? I'd like to be able to group them by quotes and such.
Example:
this="'hi there' name here"
for argument in $this; do
echo "$argument"
done
which should print (but obviously doesn't)
hi there
name
here
Upvotes: 2
Views: 229
Reputation: 531055
Don't store the arguments in a string. Arrays were invented for this purpose:
this=('hi there' name here)
for argument in "${this[@]}"; do
echo "$argument"
done
It is highly recommended that you use this approach if you have control over this
. If you don't, that is even more reason not to use eval
, since unintended commands can be embedded in the value of this
. For example:
$ this="'hi there'); echo gotcha; foo=("
$ eval args=($this)
gotcha
Less nefarious is something as simple as this="'hi there' *"
. eval
will expand the *
as a pattern, matching every file in the current directory.
Upvotes: 2
Reputation: 785058
Using gsed -r
:
echo "$this" | gsed -r 's/("[^"]*"|[^" ]*) */\1\n/g'
"hi there"
name
here
Using egrep -o
:
echo "$this" | egrep -o '"[^"]*"|[^" ]+'
"hi there"
name
here
Pure BASH way:
this="'hi there' name here"
s="$this"
while [[ "$s" =~ \"[^\"]*\"|[^\"\ ]+ ]]; do
echo ${BASH_REMATCH[0]}
l=$((${#BASH_REMATCH[0]}+1))
s="${s:$l}"
done
"hi there"
name
here
Upvotes: 1
Reputation: 2632
I worked out a half-answer myself. Consider the following code:
this="'hi there' name here"
eval args=($this)
for arg in "${args[@]}"; do
echo "$arg"
done
which prints the desired output of
hi there
name
here
Upvotes: 2