在循环中访问循环变量

在循环中访问循环变量

这是我的脚本:

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

你的问题是被解释为and$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. 满足您需要的更 bash 方式:
尝试这个:
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

数学扩展将扩展 shell 变量第一的。当它完成时,它会得到一个如下所示的语句:

sum_[1234] = load_[1234] + f4

...其中括号表示循环中的每次迭代,这是有效的算术语法,因为字符串表示 shell 算术扩展中整数的变量名称。即使它被用作[ test ]-so的参数,它也会在当前 shell 上下文中设置这些变量,$sum_1同时将其设置为值15231并与之比较的$min0.

但根据您的价值观$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

相关内容