简体   繁体   English

如何用 bash 中的变量替换数组元素?

[英]How to substitute array element with a variable in bash?

I've got about 10 arrays like so:我有大约 10 个 arrays 像这样:

array_1=("Mike" "George" "Sam" "1234" "5678")
array_2=("Albert" "Isabel" "Sami" "4567" "9821")
array_3=("Michel" "Tom" "Cathy" "321" "5664")
array_4=("name 1" "name 2" "name 3" "1233" "4567")
array_5=...

To get single array elements (this is needed because not all are used in the script):要获取单个数组元素(这是必需的,因为脚本中并未使用所有元素):

name1="${array_1[0]}"
name2="${array_1[1]}"
name3="${array_1[2]}"
number1="${array_1[3]}"
number2="${array_1[4]}"

Sometimes I want to use array_2 (or 3/4..) instead of array_1.有时我想使用array_2(或3/4 ..)而不是array_1。 To avoid replacing (array_1) in all the lines of the names and numbers, I'm looking to use a simple variable substitution, so tried to replace with different kind of quotes, including:为了避免在名称和数字的所有行中替换 (array_1),我希望使用简单的变量替换,因此尝试用不同类型的引号替换,包括:

myarray="array_1" // also tried 'array_1' and $array_1
name1="${myarray[0]}" // also tried "${$!myarray[0]}" and different quotes combinations

At this point I'm a bit confused about how bash quotes and probably indirects may work for this example, none the found answers nor various tries worked so far, aiming to see if there is rather a simple approach to address this or should the way of how arrays are being used here needs to be changed.在这一点上,我对 bash 引用和可能的间接引用如何适用于这个例子有点困惑,到目前为止,没有找到的答案和各种尝试都有效,旨在看看是否有一个相当简单的方法来解决这个问题或应该的方式此处需要更改 arrays 的使用方式。 Any hint is appreciated.任何提示表示赞赏。

You need to make myarray a nameref with declare -n .您需要使用declare -n使myarray成为 nameref。

declare -n myarray=array_1

Then you reference it as if it were the named array:然后你引用它,就好像它是命名数组一样:

$ echo "${myarray[0]}"
Mike

Note that this only works in bash 4.3+, however.但是请注意,这只适用于 bash 4.3+。 Apple is allergic to GPL v3+ so macOS ships with 3.2 in /bin; Apple 对 GPL v3+ 过敏,因此 macOS 在 /bin 中附带 3.2; if you're on a Mac, you'll need to install a newer version (eg with MacPorts or Homebrew).如果您使用的是 Mac,则需要安装更新的版本(例如,使用 MacPorts 或 Homebrew)。

If your bash is too old for namerefs you can use indirection:如果您的 bash 对于 namerefs 来说太旧了,您可以使用间接:

array=array_1
name1="${!array[0]}"
name2="${!array[1]}"
name3="${!array[2]}"
number1="${!array[3]}"
number2="${!array[4]}"

Demo:演示:

$ array=array_1
$ name1="${!array[0]}"
$ echo "$name1"
Mike
$ array=array_2
$ name1="${!array[0]}"
$ echo "$name1"
Albert

@Mike @麦克风

Proceed as per comment from Mark Reed.按照 Mark Reed 的评论继续。
I thought of sharing:我想到了分享:
$ cat "73180037.sh" $猫“73180037.sh”
#!/bin/bash #!/bin/bash
array_1=("Mike" "George" "Sam" "1234" "5678") array_1=("迈克" "乔治" "山姆" "1234" "5678")
array_2=("Albert" "Isabel" "Sami" "4567" "9821") array_2=("阿尔伯特" "伊莎贝尔" "萨米" "4567" "9821")
array_3=("Michel" "Tom" "Cathy" "321" "5664") array_3=("米歇尔""汤姆""凯茜""321""5664")
array_4=("name 1" "name 2" "name 3" "1233" "4567") array_4=("名称 1" "名称 2" "名称 3" "1233" "4567")
array_5=...数组_5=...
for i in {1..5}对于我在 {1..5}
do
name1=array_$i[0]; name1=array_$i[0];
name2=array_$i[1]; name2=array_$i[1];
name3=array_$i[2]; name3=array_$i[2];
number1=array_$i[3]; number1=array_$i[3];
number2=array_$i[4]; number2=array_$i[4];
echo ${!name1} ${!name2} ${!name3} ${!name3} ${!number1} ${!number2}回声 ${!name1} ${!name2} ${!name3} ${!name3} ${!number1} ${!number2}
done完毕

You kind of need, an array of array which does not supported in but it does not mean you cannot make it您有点需要, 中不支持的数组数组,但这并不意味着您不能做到

Here is a dirty way of having an array of array with quick access这是一种快速访问数组的肮脏方式

script脚本

#!/bin/bash

# bash strict mode
set -C
set -Ee
set -T
set -u
set -o pipefail

# global array
declare -a arr=();

# get each line as an array, start from 0
function array_of_array(){
    # get the index
    declare -r index=${1:?'Error: first arg is needed'};

# each line is an array
# delimiter is comma ,
data="name surname 11, name surname 12, 123, 456
name surname 21, name surname 22, 123, 456, 789
name surname 31, name surname 32, 123, 456";

    # extract that line, start from 0
    mapfile -s $index  -t array <<< "$data";

    # delimiter is ,
    IFS=',';

    # remove space after comma
    array=${array//, /,}

    # save it in arr, a global variable
    read -a arr <<< "${array[0]}";
}


# read first line into an array
# read -a arr  <<< "$(array_of_array 0)"
array_of_array 0
echo
echo '### first ###'
echo arr: "${arr[0]}"
echo arr: "${arr[1]}"
echo arr: "${arr[2]}"
echo arr: "${arr[3]}"
echo size: "${#arr[@]}"


# read second line into an array
# read -a arr <<< "$(array_of_array 1)"
array_of_array 1
echo
echo '### second ###'
echo arr: "${arr[0]}"
echo arr: "${arr[1]}"
echo arr: "${arr[2]}"
echo arr: "${arr[3]}"
echo arr: "${arr[4]}"
echo size: "${#arr[@]}"


sample output样品 output


### first ###
arr: name surname 11
arr: name surname 12
arr: 123
arr: 456
size: 4

### second ###
arr: name surname 21
arr: name surname 22
arr: 123
arr: 456
arr: 789
size: 5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM