2015-08-13 2 views
0

Я нашел несколько вопросов о Stackoverflow, которые похожи, но не смог извлечь нужный ниндзя bash, поэтому я нахожусь в кепке в руке, чтобы кто-то меня ввел. Я использую скрипт bash для загрузки некоторых котировок валют. Кавычки находятся в большом текстовом файле, и я использую grep и cut, чтобы извлечь их. Все идет нормально. Все котировки против доллара США. Я загружаю три файла из текущих ставок, месяц назад и год назад. Вот код, который я придумал с помощью 'declare', чтобы динамически устанавливать имена переменных. Этот бит работает отлично.Сценарий оболочки Bash: динамически генерируемые переменные массива

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, у меня есть массив с ключом - паром значений, как это:

${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 его, я получаю «плохую замену» сообщение. Я перехожу к этому, пытаясь использовать разные вещи с помощью eval и даже других методов, отмеченных как verboten в других вопросах (так что я не буду их преследовать здесь). Может ли кто-нибудь указать мне в правильном направлении? Используя Bash 4.3, если это поможет.

ВОПРОС БОНУСА. В моей отладке я пытаюсь использовать echo $ {! HKD [@]} для просмотра имен ключей. Несмотря на все, что написано повсюду в Интернете, оно не работает. Хотя $ {HKD [@]} дает мне значения. Есть идеи об этом?

+0

Пример вывода этого окончательного отчета эха ** объявить HKD [GBP] = 'echo $ {HKD [USD]}/$ {GBP [USD]} | bc' ** Выполнение eval на том, что вместо эха, похоже, не добавляет переменные. – plutocrat

ответ

0

Вам не нужно eval; вам просто нужно косвенное расширение параметра. Заменить

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

с

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

(Несмотря на синтаксис окраски здесь, двойные кавычки внутри $(...) отличаются от двойных кавычек вмещающих весь аргумент declare, гнездящихся работы.)

+0

Спасибо. Это похоже на работу, а также ... Я узнал новый трюк!На самом деле два: вместо << эха вместо << эхо был новый. Итак, теперь только тайна почему 'echo $ {! HKD [@]}' ничего не перечисляет. Может быть, я должен поставить это в другом вопросе. – plutocrat

+0

Возможно. Непонятно, почему это не сработает, поскольку «HKD» является ассоциативным массивом, независимо от того, как он был объявлен. – chepner

0

Argh. Хорошо, так что, вероятно, в плохой форме, я отвечаю на свой вопрос. По-видимому, у меня почти было это, мне просто нужно было настроить линию эха/эваль. Это работает eval "declare $CURRENCY[${TARGETCURRENCY}]=\$(echo \${$CURRENCY[USD]}/\${$TARGETCURRENCY[USD]} | bc)" Кажется, что часть проблемы заключалась в том, что я использовал устаревшую форму backquotes. Изменение его в $() казалось, было исправлением, хотя я изменил и многие другие вещи, так трудно сказать, когда я получил магическую формулу.

OK, так что просто возникает вопрос о том, почему $ {! HKD [@]} не работает, чтобы перечислить имена ключей/индексов.

Смежные вопросы