event_jr
event_jr

Reputation: 17707

How to separate string into shell arguments?

I have this test variable in ZSH:

test_str='echo "a \" b c"'

I'd like to parse this into an array of two strings ("echo" "a \" b c").

i.e. Read test_str as the shell itself would and give me back an array of arguments.

Please note that I'm not looking to split on white space or anything like that. This is really about parsing arbitrarily complex strings into shell arguments.

Upvotes: 4

Views: 3279

Answers (2)

ZyX
ZyX

Reputation: 53614

Zsh has (z) modifier:

ARGS=( ${(z)test_str} )

. But this will produce echo and "a \" b c", it won’t unquote string. To unquote you have to use Q modifier:

ARGS=( ${(Q)${(z)test_str}} )

: results in having echo and a " b c in $ARGS array. Neither would execute code in or $(…), but (z) will split $(false true) into one argument.

that is to say:

% testfoo=${(z):-'blah $(false true)'}; echo $testfoo[2]
$(false true)

Upvotes: 9

William Pursell
William Pursell

Reputation: 212248

A simpler (?) answer is hinted at by the wording of the question. To set shell argument, use set:

#!/bin/sh

test_str='echo "a \" b"'
eval set $test_str
for i; do echo $i; done

This sets $1 to echo and $2 to a " b. eval certainly has risks, but this is portable sh. It does not assign to an array, of course, but you can use $@ in the normal way.

Upvotes: 5

Related Questions