繁体   English   中英

Bash Shell脚本:动态生成数组变量

[英]Bash shell script: dynamically generating array variables

我在Stackoverflow上发现了一些类似的问题,但是无法提取必要的bash忍者,所以我要亲自给别人提供线索。我正在使用bash脚本下载一些货币报价。 引号在一个大的文本文件中,我使用grep并剪切以提取它们。 到现在为止还挺好。 所有报价均兑美元。 我从一个月前和一年前的当前费率下载了三个文件。 这是我使用'declare'动态设置变量名的代码。 这一点工作正常。

for CURRENCY in GBP HKD EUR
do
    # Get rates against USD
    declare -A $CURRENCY
    TODAY=`grep $CURRENCY today.json | cut -f 2 -d: | tr -d "," | tr -d " "`
    MONTH=`grep $CURRENCY month.json | cut -f 2 -d: | tr -d "," | tr -d " "`
    YEAR=`grep $CURRENCY year.json | cut -f 2 -d: | tr -d "," | tr -d " "`
    declare ${CURRENCY}[USD]=$TODAY
    declare ${CURRENCY}[USD_M]=$MONTH
    declare ${CURRENCY}[USD_Y]=$YEAR
    # Get inverse rate
    declare ${CURRENCY}[USD_I]=`echo "scale=5; 1/$TODAY" | bc`
    declare ${CURRENCY}[USD_M_I]=`echo "scale=5; 1/$MONTH" | bc`
    declare ${CURRENCY}[USD_Y_I]=`echo "scale=5; 1/$YEAR" | bc`

done

所以现在,例如每种货币 英镑,我有一个包含键-值对的数组,如下所示:

${GBP[USD]} = 0.65
${GBP[USD_M]} = 0.63
${GBP[USD_Y]} = 0.70 etc.

是的,所以我想遍历每种货币并相互生成每种货币的价值。 即获得$ {GBP [HKD]} $ {GBP [EUR]} $ {HKD [GBP]} $ {HKD [EUR]} $ {EUR [GBP]} $ {EUR [HKD]}。 这就是开始变得棘手的地方。

我启动了另一个循环来尝试此操作,但错过了货币与自身匹配(汇率= 1)的情况。 为了获得第一个值,例如,我想将$ {GBP [USD]}除以$ {HKD [USD]}。

for CURRENCY in GPB HKD EUR
do
   for TARGETCURRENCY in GPB HKD EUR
    do 
    if [ "$TARGETCURRENCY" != "$CURRENCY" ]; then

    echo "declare $CURRENCY[$TARGETCURRENCY]=\`echo \${$CURRENCY[USD]}/\${$TARGETCURRENCY[USD]} | bc\`"
    fi  
         done
done

我可以在上面的循环中回显我想执行的命令,但是如果我尝试对其进行评估,则会收到消息“错误替换”。 我一直在反复研究,尝试用eval尝试各种方法,甚至在其他问题中尝试其他标记为verboten的方法(因此在这里我不会烦恼它们)。 有人可以指出我正确的方向吗? 如果有帮助,请使用Bash 4.3。

奖金问题。 在调试中,我一直在尝试使用echo $ {!HKD [@]}查看密钥名称。 尽管互联网上到处都写着所有东西,但它不起作用。 尽管$ {HKD [@]}确实为我提供了这些值。 有什么想法吗?

好的,所以我可能会以一种不好的形式回答我自己的问题。 显然我快要掌握了,我只需要调整回声/评估线。 这个eval "declare $CURRENCY[${TARGETCURRENCY}]=\\$(echo \\${$CURRENCY[USD]}/\\${$TARGETCURRENCY[USD]} | bc)"有效, eval "declare $CURRENCY[${TARGETCURRENCY}]=\\$(echo \\${$CURRENCY[USD]}/\\${$TARGETCURRENCY[USD]} | bc)"看来问题的一部分在于,我正在使用旧的反引号形式。 将其更改为$()似乎是解决问题的方法,尽管我也更改了许多其他内容,所以很难说出何时获得了魔术公式。

好的,这样就剩下一个问题了,为什么$ {!HKD [@]}无法列出键/索引名称。

你不需要eval ; 您只需要间接参数扩展。 更换

declare $CURRENCY[$TARGETCURRENCY]=\`echo \${$CURRENCY[USD]}/\${$TARGETCURRENCY[USD]} | bc\`

numerator=$CURRENCY[USD]
denominator=$TARGETCURRENCY[USD]
declare "$CURRENCY[$TARGETCURRENCY]=$(bc <<< "${!numerator}/${!denominator}")"

(尽管此处使用语法着色,但$(...)中的双引号与将整个参数括起来进行declare的双引号不同;嵌套有效。)

暂无
暂无

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

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