Bash - 紧凑地从数组中解压缩元素?

时间:2017-07-21 15:39:33

标签: bash

是否有更紧凑的替代

arr=( 1 2 3 )
e1=${arr[0]}
e2=${arr[1]}
e3=${arr[2]}

类似的东西,

e1, e2, e3=${arr[@]}

2 个答案:

答案 0 :(得分:1)

如果您的数组元素中没有空格,那么您可以在shell中使用默认read值(空格)IFS

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"

答案 1 :(得分:1)

一般来说,提出这个问题意味着您不应该首先使用数组作为数据。

也就是说,以下功能可以重复使用并且正确 - 没有任何警告可以使用和不能使用哪些数据:

array_to_vars() {
  declare -n _arr=$1
  local var
  for var; do
    shift || return
    printf -v "$var" %s "$1"
  done
}

......可用作:

# put first element of arr into e1, second into e2, third into e3
# disregard the rest
array_to_vars arr e1 e2 e3

它不像人们想要的那么短,但它不太可能导致错误,因为它只适用于不含有印记的数据。

让我们说你像这样填充它:

read -r -a arr < <(command-that-generates-a-list)

您可以将其替换为:

read -r e1 e2 e3

或者让我们说出来:

arr=( )
while read -r line; do
  arr+=( "$line" )
done < <(command-that-generates-a-list)

您可以将其替换为:

{ read -r e1; read -r e2; read -r e3; } < <(command-that-generates-a-list)

或与:

{ IFS=$'\n' read -r -d '' e1 e2 e3; } < <(command-that-generates-a-list && printf '\0')

或者让我们说出来:

arr=(${string//,/ })

...在这种情况下,它会更简单,更正确(避免不希望的行为,如全局扩展 - 请参阅BashPitfalls #50):

IFS=, read -r e1 e2 e3 <<<"$string"