在bash中嵌套变量和循环

时间:2017-03-27 16:40:36

标签: arrays bash

我无法弄清楚(使用我有限的bash脚本技能)如何解决这个问题,我想以某种方式在bash脚本中组合变量。我正在尝试以下方法:

#!/bin/bash
basearch=x86_64
ol7_channels="ol UEKR4 UEKR3"
ol6_channels="ol UEKR4 UEKR3 UEK"
ol5_channels="ol UEK"

for version in 7 6 5
do
  for channel in ${ol${version}_channels}}
  do
    printf "Oracle Linux $version $channel $basearch"
  done
done

理想的输出是:

OracleLinux 7 ol x86_64

OracleLinux 7 UEKR4 x86_64

OracleLinux 7 UEKR3 x86_64

OracleLinux 6 ol x86_64

OracleLinux 6 UEKR4 x86_64

OracleLinux 6 UEKR3 x86_64

OracleLinux 5 ol x86_64

OracleLinux 5 UEKR4 x86_64

OracleLinux 5 UEKR3 x86_64

我理解将变量放在变量中,就像我已经完成的那样。 有谁能告诉我如何实现这个目标?

3 个答案:

答案 0 :(得分:2)

下面实际使用的是真正的数组(而不是将字符串视为数组),并使用bash 4.3特性namerefs为这些数组创建别名。

#!/bin/bash
basearch=x86_64
channels_ol7=( ol UEKR4 UEKR3 )
channels_ol6=( ol UEKR4 UEKR3 UEK )
channels_ol5=( ol UEK )

for varname in "${!channels_ol@}"; do # iterate over variables starting with channels_ol
  version=${varname#channels_ol}      # trim prefix to get version number
  declare -n channels=$varname        # point channels nameref at our array
  for channel in "${channels[@]}"; do # iterate over that array
    printf 'Oracle Linux %s %s %s\n' "$version" "$channel" "$basearch"
  done
  unset -n channels                   # clear the nameref before proceeding
done

答案 1 :(得分:2)

另一种方法:

#!/bin/bash

#bash 4.0+

basearch=x86_64
declare -A channels=(
        [7]="ol UEKR4 UEKR3"
        [6]="ol UEKR4 UEKR3 UEK"
        [5]="ol UEK"
)

#or for version in 5 6 7 #if you need ordered
for version in "${!channels[@]}"
do
        read -a chanlist <<<"${channels[$version]}"
        for channel in "${chanlist[@]}"
        do
            echo "$version $channel $basearch"
        done
        #or replace the whole "for channel" loop with the following line
        #printf "$version %s $basearch\n" "${chanlist[@]}"
        #but read charles's comment
done

输出

7 ol x86_64
7 UEKR4 x86_64
7 UEKR3 x86_64
6 ol x86_64
6 UEKR4 x86_64
6 UEKR3 x86_64
6 UEK x86_64
5 ol x86_64
5 UEK x86_64

答案 2 :(得分:0)

您可以手动撰写变量,然后使用variable indirect reference

#!/bin/bash
basearch=x86_64
ol7_channels="ol UEKR4 UEKR3"
ol6_channels="ol UEKR4 UEKR3 UEK"
ol5_channels="ol UEK"

for version in 7 6 5
do
  varname="ol${version}_channels";
  for channel in "${!varname}"
  do
    echo "Oracle Linux $version $channel $basearch"
  done
done

嵌套变量名do not work in bash