I don't remember where I saw this first - probably in the Debian Installer code. Anyway, given an n-tuple it can be somewhat unwieldy to unpack it:
VAR="Aho Sethi Ullman" ONE="$(echo ${VAR} | cut -d' ' -f1)" TWO="$(echo ${VAR} | cut -d' ' -f2)" THREE="$(echo ${VAR} | cut -d' ' -f3)"
The trick being presented is to generate the boilerplate code and then eval it:
VAR="Aho Sethi Ullman" eval $(echo ${VAR} | awk '{ print "ONE=" $1 " TWO=" $2 " THREE=" $3 }')
Here's a more concrete example, with apologies to Python:
for PAIR in \ "one Aho" \ "two Sethi" \ "three Ullman" do eval $(echo ${PAIR} | awk '{ print "k=" $1 " v=" $2 }') # .. do something with $k and $v done
nice trick, but it fails if the input data contains the same quotes you use to try to protect it from the eval
(quoting: number one reason to hate shell code)
Joey Hess
— lamby
Better yet:
#!/bin/bash
...
VAR="Aho Sethi Ullman"
...
a=($VAR)
# do stuff with ${a[0]}, ${a[1]}, ${a[2]}
Anonymous
— lamby
In most of these cases, you ought to let the shell do the splitting, e.g.
set -- Aho Sethi Ullman
echo $3 $2 $1
or
while read k v; do something $k $v; done <<_eof
red green
blue yellow
_eof
madduck
— lamby
Here's something of the type which I did the other day:
#!/bin/bash
pos -l8 $* | { read LAT LONG
echo Latitude = $LAT
echo Longitude = $LONG
# gnome-open "http://maps.google.com/?ie=UTF8&ll=${LAT},${LONG}&spn=0.003117,0.009656&z=17"
gnome-open "http://www.openstreetmap.org/?lat=${LAT}&lon=${LONG}&zoom=18&layers=B000FTF"
}
("pos" is my own little utility which converts various flavours of latitude/longitude or Ordnance Survey grid reference to various other flavours of the same.)
The "scope" of the result can be regarded as a PITA or quite elegant depending...
Ed Davies
A bit off-topic here, but still... Yesterday I had to fiddle a bit with bash quoting and evaluation, as I am working on a specific-purpose system installer - The only user interaction I have is via this loop:
for conf in HD CDR SWAP_SIZE CONF_URL
do
echo -n "$conf: (default = ${!conf}): "
read tempvar
if [ ! -z "$tempvar" ]
then
eval ${conf}=\$tempvar
fi
done
I had to squeeze my brain (and bash's manpage) for the indirect expansion (${!conf}) and for the proper way for the assignment... It is still breakable, but tolerably so at least.
Gunnar