如何动态获取变量名

时间:2021-01-07 23:38:16
#!/bin/bash
year="${1:0:4}";month="${1:4:2}";day="${1:6:2}"

element=('Wood' 'Fire' 'Earth' 'Metal' 'Water')

rat=(05021924 23021925 24011936 10021937 10021948 28011949 28011960 14021961 15021972 02021973 02021984 19021985 19021996 06021997 07022008 25012009 25012020 11022021 11022032 30012033)

pig=(04021935 23011936 22011947 09021948 08021959 27011960 27011971 14021972 13021983 01021984 31011995 18021996 18022007 06022008 05022019 24012020 23012031 10022032 10022043 29012044)

Scounter=0
Ecounter=1

for (( i=0; i<10; i++ )) #10 is the number of date RANGES
do
        echo $i
#done

#echo "start of year"
#Make sure that the base value for Month and Day is base 10 and not base 8. Base 8 is a number starting with 0.
    sDay=${rat[$Scounter]:0:2};sMonth=${rat[$Scounter]:2:2};sYear=${rat[$Scounter]:4:4}
#echo "end of year"
    eDay=${rat[$Ecounter]:0:2};eMonth=${rat[$Ecounter]:2:2};eYear=${rat[$Ecounter]:4:4}

#10base conversion
#month=$((10#$month))
#day=$((10#$day))
#sMonth=$((10#$sMonth))
#sDay=$((10#$sDay))
#eMonth=$((10#$eMonth))
#eDay=$((10#$eDay))

    if [[ $year -eq $sYear && $month -ge $sMonth && $day -ge $sDay ||  $year -eq $eYear && $month -le $eMonth && $day -le $eDay ]]
    then
        if [[ $i -gt 4 ]]
        then
            echo "${element[$((i-5))]} rat"
        else
            echo "${element[$i]} rat"
        fi
        fi

    Scounter=$((Scounter+2))
    Ecounter=$((Ecounter+2))
done

I am trying to replace the "rat" in sDay,sMonth,sYear ,etc. with a variable that will point to the array rat or pig. I have tried using substitution by putting

我正在努力取代“老鼠”在星期三,月,年等。使用指向数组rat或pig的变量。我试过用代换法。

sDay=${$rat[$Scounter]:0:2};

But I get a substitution error

但是我得到了一个代换误差

By the way I'm working on a Chinese Zodiac script.

顺便说一下,我正在写一个中国生肖脚本。

1 个解决方案

#1


4  

I believe that you are looking for indirection:

我相信你是在寻找间接的:

$ rat=(05021924 23021925 24011936 10021937 10021948 28011949 28011960 14021961 15021972 02021973 02021984 19021985 19021996 06021997 07022008 25012009 25012020 11022021 11022032 30012033)
$ y="rat[1]"; echo "${!y}"
23021925
$ y="rat[1]"; echo "${!y:0:2}"
23

Using the above as part of a loop:

将以上内容作为循环的一部分:

for x in rat pig
do
    for i in 0 1
    do
        y="$x[$i]"
        echo "$x $i ${!y}"
    done
done

Which produces the output:

生成的输出:

rat 0 05021924
rat 1 23021925
pig 0 04021935
pig 1 23011936

Documentation

From man bash:

从人抨击:

${parameter}
The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one digit, or when parameter is followed by a character which is not to be interpreted as part of its name. The parameter is a shell parameter as described above PARAMETERS) or an array reference (Arrays).

${parameter}参数的值被替换。当参数是具有多个数字的位置参数时,或者当参数后面跟着不被解释为其名称一部分的字符时,需要使用大括号。参数是如上所述的shell参数或数组引用(数组)。

If the first character of parameter is an exclamation point (!), it introduces a level of variable indirection. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion. The exceptions to this are the expansions of ${!prefix*} and ${!name[@]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection. [Emphasis added.]

如果参数的第一个字符是感叹号(!),则会引入一个可变的间接层。Bash使用由其余参数组成的变量的值作为变量的名称;然后展开该变量,该值将在替换的其余部分中使用,而不是参数本身的值。这就是所谓的间接扩张。例外是${!前缀* }和$ { !名字下面描述[@]}。感叹号必须立即跟随左括号,以便引入间接引语。(重点补充。)

#1


4  

I believe that you are looking for indirection:

我相信你是在寻找间接的:

$ rat=(05021924 23021925 24011936 10021937 10021948 28011949 28011960 14021961 15021972 02021973 02021984 19021985 19021996 06021997 07022008 25012009 25012020 11022021 11022032 30012033)
$ y="rat[1]"; echo "${!y}"
23021925
$ y="rat[1]"; echo "${!y:0:2}"
23

Using the above as part of a loop:

将以上内容作为循环的一部分:

for x in rat pig
do
    for i in 0 1
    do
        y="$x[$i]"
        echo "$x $i ${!y}"
    done
done

Which produces the output:

生成的输出:

rat 0 05021924
rat 1 23021925
pig 0 04021935
pig 1 23011936

Documentation

From man bash:

从人抨击:

${parameter}
The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one digit, or when parameter is followed by a character which is not to be interpreted as part of its name. The parameter is a shell parameter as described above PARAMETERS) or an array reference (Arrays).

${parameter}参数的值被替换。当参数是具有多个数字的位置参数时,或者当参数后面跟着不被解释为其名称一部分的字符时,需要使用大括号。参数是如上所述的shell参数或数组引用(数组)。

If the first character of parameter is an exclamation point (!), it introduces a level of variable indirection. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion. The exceptions to this are the expansions of ${!prefix*} and ${!name[@]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection. [Emphasis added.]

如果参数的第一个字符是感叹号(!),则会引入一个可变的间接层。Bash使用由其余参数组成的变量的值作为变量的名称;然后展开该变量,该值将在替换的其余部分中使用,而不是参数本身的值。这就是所谓的间接扩张。例外是${!前缀* }和$ { !名字下面描述[@]}。感叹号必须立即跟随左括号,以便引入间接引语。(重点补充。)