Preamble: Care using eval
as eval is evil...
Whatever...
bash could do this very quickly:
unset ${x//=*([^ ])}
As pointed out by glenn jackman, this work only if there are no spaces in content of variables.
In this case, we could (very quickly too) prepare some intermediary variable (x without spaces
):
xwos=${x//\"*([^\"])\"} # This will drop `search="don't know"`
xwos=${xwos//\'*([^\'])\'} # This will drop `search='blah blah'`
unset ${xwos//=*([^ ])}
In fine, adding this to your script will do the job:
xwos=${x//\"*([^\"])\"}; xwos=${xwos//\'*([^\'])\'}; unset ${xwos//=*([^ ])}
Explanation / showcase
Of course, you have to use extglob
bash's option, if not already set:
shopt -s extglob
Let's try:
x="search='something something' replace='something' subject=/path/path"
eval "$x"
echo $search
something something
declare -p search replace subject
declare -- search="something something"
declare -- replace="something"
declare -- subject="/path/path"
shopt -s extglob
xwos=${x//\"*([^\"])\"}
printf 'X w/o double quoted spaces 1st:\n "%s"\n' "$xwos"
X w/o double quoted spaces 1st:
"search='something something' replace='something' subject=/path/path"
xwos=${xwos//\'*([^\'])\'}
printf 'X w/o single quoted spaces 2nd:\n "%s"\n' "$xwos"
X w/o single quoted spaces 2nd:
"search= replace= subject=/path/path"
printf 'String containing variables w/o values:\n "%s"\n' "${xwos//=*([^ ])}"
String containing variables w/o values:
"search replace subject"
unset ${xwos//=*([^ ])}
declare -p search replace subject
bash: declare: search: not found
bash: declare: replace: not found
bash: declare: subject: not found
Nota: If you don't need x
anymore, you could redefine x
instead of populating a new variable:
shopt -s extglob;x=${x//\"*([^\"])\"};x=${x//\'*([^\'])\'};unset ${x//=*([^ ])}
Demo
x="search='something something' replace='something' subject=/path/path"
eval "$x"
echo $search
something something
shopt -s extglob;x=${x//\"*([^\"])\"};x=${x//\'*([^\'])\'};unset ${x//=*([^ ])}
echo $search