ループからループ変数にアクセスする

ループからループ変数にアクセスする

これは私のスクリプトです。

load_1=15231
load_2=20547
load_3=24561
load_4=22874
f4=434

   sum_1=`expr $load_1 + $f4`
   sum_2=`expr $load_2 + $f4`
   sum_3=`expr $load_3 + $f4`
   sum_4=`expr $load_4 + $f4`

   min=$sum_1
   LIST1="1 2 3 4"
   for x in $LIST1
    do
     if [ $sum_$x -lt $min ]
      then
       min=$sum_$x
       f3=$x
     fi
    done
   echo $min
   echo $f3

次のコマンドを使用してスクリプトを実行したときの出力は次のとおりですbash -x

+ load_1=15231
+ load_2=20547
+ load_3=24561
+ load_4=22874
+ f4=434
++ expr 15231 + 434
+ sum_1=15665
++ expr 20547 + 434
+ sum_2=20981
++ expr 24561 + 434
+ sum_3=24995
++ expr 22874 + 434
+ sum_4=23308
+ min=15665
+ LIST1='1 2 3 4'
+ for x in '$LIST1'
+ [[ 1 -lt 15665 ]]
+ min=1
+ f3=1
+ for x in '$LIST1'
+ [[ 2 -lt 1 ]]
+ for x in '$LIST1'
+ [[ 3 -lt 1 ]]
+ for x in '$LIST1'
+ [[ 4 -lt 1 ]]
+ echo 1
1
+ echo 1
1

ループ変数 "x"の値をテスト条件変数に置き換え、次の値sum_x$sum_xテスト条件に割り当てる必要があります。しかし、出力からわかるように、 'x'値は条件に直接適用されます。私は引用符と括弧のさまざまな組み合わせを試しましたが、何も効果がありませんでした。助けてください! !

答え1

$sum_$xあなたの質問は次のリンクとして解釈されます。$sum_$x

~$ for x in $LIST1;  do   echo $sum_$x;  done
1
2
3
4

したがって、あなたの質問です。あなたが望むものは使用することです

~$ for x in $LIST1;  do   echo $((sum_$x));  done
15665
20981
24995
23308

答え2

私はあなたのスクリプトが何をすべきかをよく理解しておらず、どの言語で書くのか教えてくれませんでした。だから私はbashを仮定し、あなたの質問に値が存在しないことを知り、スクリプトを実行しないことを知っています。とても役に立つことをしなさい

通常、変数名を取得するために文字列を連結するのは面倒で不要です。単に配列を使用してください:

#!/usr/bin/env bash
load=(15231 20547 24561 22874)
f4=434

for((i=0;i<${#load[@]};i++))
do
    sums[i]=$((${load[i]} + $f4))
done

min=$((${sums[0]}))
for((i=1;i<${#load[@]};i++))
do
    if [ "${sums[i]}" -lt "$min" ]
    then
       min="${sums[i]}"
       f3="$i"
    fi
done

printf "%s\n%s" "$min" "$f3"

答え3

  1. あなたのニーズに合ったもう少しバッシュな方法:
この試み:
load_1=15231  
load_2=20547  
load_3=24561
load_4=22874
f4=434
line=`(set -o posix ; set) | grep load_  | sort -t = -n -k2 | head -1`
min=`echo $line | cut -d= -f2`
echo $((min+f4))
echo $line | cut -d= -f1 | cut -d_ -f2

その結果は次のとおりです。 15665 1

それでもコードを使用したい場合は、次の手順に従ってください。

  1. LIST1使用を避けることができますfor x in {1..4}

  2. f3=1設定すると設定されますmin。それ以外の場合は、例のように設定されません。

答え4

load_1=15231
load_2=20547
load_3=24561
load_4=22874
f4=434
min=0
f3=1

for n in 1 2 3 4
do   [ "$((sum_$n=load_$n+f4))" -lt \
       "$((min=min?min:sum_$n))" ] &&
     min=$((sum_$n)) f3=$n
     printf '$%s =\t%d\n' \
            "sum_$n" "$((sum_$n))" \
             min "$min" f3 "$f3"
done

数学拡張はシェル変数を拡張します。最初。完了すると、次の文が表示されます。

sum_[1234] = load_[1234] + f4

...ここで、括弧はループの各反復を表します。これは、文字列がシェル算術拡張の整数の変数名を表すため、有効な算術構文です。[ test ]-soの引数として使用されていても、現在のシェルコンテキストでこれらの変数を設定し、$sum_1同時に値に設定します。15231そして$minそれと比較すると0

ただし、値は決して小さくはないため、お客様の値に応じて$min調整されません。$sum_$n$sum_$n$min

出力

$sum_1 =    15665
$min =  15665
$f3 =   1
$sum_2 =    20981
$min =  15665
$f3 =   1
$sum_3 =    24995
$min =  15665
$f3 =   1
$sum_4 =    23308
$min =  15665
$f3 =   1

実際、私たちはすべてを数学的に拡張し、テストを完全に省略することができます。

load_1=15231
load_2=20547
load_3=24561
load_4=22874
f4=434
f3=$((!(min=0)))
for n in 1 2 3 4
do  echo \$min = "$((
           min = ( min    >  ( sum_$n = load_$n+f4 ) )
               ? ( sum_$n + !( f3     = $n         ) )
               : ( min    ?    min    : sum_$n     )
))"; done

これは各反復に対してすべての変数を適切に設定しますが、$min毎回値としてのみ拡張されます。次のように印刷されます。

$min = 15665
$min = 15665
$min = 15665
$min = 15665

関連情報