Reputation: 20365
Is there a more compact alternative to
arr=( 1 2 3 )
e1=${arr[0]}
e2=${arr[1]}
e3=${arr[2]}
?
Something like,
e1, e2, e3=${arr[@]}
Upvotes: 5
Views: 3395
Reputation: 295679
Generally speaking, asking this question implies that you shouldn't be using an array for your data in the first place.
That said, the following function is reusable and correct -- with no caveats around which data it can and can't be used for:
array_to_vars() {
declare -n _arr=$1
local var
for var; do
shift || return
printf -v "$var" %s "$1"
done
}
...usable as:
# put first element of arr into e1, second into e2, third into e3
# disregard the rest
array_to_vars arr e1 e2 e3
It's not as short as one might like, but it's less likely to cause bugs as something that works only for data not containing a sigil.
Let's say you're populating it like so:
read -r -a arr < <(command-that-generates-a-list)
You could replace that with:
read -r e1 e2 e3
Or let's say it's:
arr=( )
while read -r line; do
arr+=( "$line" )
done < <(command-that-generates-a-list)
You could that replace that with:
{ read -r e1; read -r e2; read -r e3; } < <(command-that-generates-a-list)
or with:
{ IFS=$'\n' read -r -d '' e1 e2 e3; } < <(command-that-generates-a-list && printf '\0')
Or let's say it's:
arr=(${string//,/ })
...in that case, it would be simpler and more correct (avoiding undesired behaviors like glob expansion -- see BashPitfalls #50) to use:
IFS=, read -r e1 e2 e3 <<<"$string"
Upvotes: 3
Reputation: 785691
If you don't have whitespaces in your array element then you can use read
using default IFS
value (whitespace) in shell:
arr=( 1 2 3 )
# unset IFS to default value it has been set earlier
unset IFS
# read content in 3 variables
read e1 e2 e3 <<< "${arr[*]}"
# examine the content of variables
declare -p e1 e2 e3
declare -- e1="1"
declare -- e2="2"
declare -- e3="3"
Upvotes: 1