acessando a variável de loop em um loop [duplicado]

0

Este é o meu script:

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

abaixo é a saída durante a execução do script usando 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

o valor da variável de loop 'x' deve ser substituído na variável de condição de teste sum_x e, em seguida, o valor de $sum_x deve ser dado à condição de teste. Mas, como mostrado na saída, o valor de 'x' é levado diretamente na condição. Eu tentei várias combinações de citações e paranthesis, mas nada funcionou para mim. Por favor ajude !!

    
por Prashanth 09.06.2015 / 11:26

4 respostas

1

Seu problema é que $sum_$x é interpretado como a concatenação de $sum_ e $x :

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

Daí o seu problema. O que você quer é usar

~$ for x in $LIST1;  do   echo $((sum_$x));  done
15665
20981
24995
23308
    
por 09.06.2015 / 11:32
0

Eu realmente não entendo o que o seu script deveria estar fazendo e você não nos disse em que língua você está escrevendo. Eu, portanto, vou assumir o bash e que você está ciente do fato de que os valores que você tem em sua pergunta não torna seu script fazer algo muito útil .

Em geral, a concatenação de strings para obter um nome de variável é bastante incômoda e desnecessária. Apenas use matrizes:

#!/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"
    
por 09.06.2015 / 15:01
0
  1. um jeito mais bash para o que você precisa:
tente isto:
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

Isso resulta em: 15665 1

se você quiser usar seu código mesmo assim:

  1. você pode evitar usar LIST1 por for x in {1..4}

  2. defina f3=1 quando definir min , caso contrário, como no seu exemplo, não está definido

por 09.06.2015 / 19:12
0
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

A expansão matemática expandirá as variáveis do shell primeiro . Quando isso acontecer, chegará a uma declaração que se parece com:

sum_[1234] = load_[1234] + f4

... onde os colchetes representam cada iteração no loop e qual é a sintaxe aritmética válida porque as strings representam nomes de variáveis para inteiros em uma expansão aritmética de shell. Ele definirá essas variáveis no contexto de shell atual mesmo quando for usado como um argumento para [ test ] - portanto, $sum_1 é definido simultaneamente para o valor 15231 e comparado a $min , que é% código%.

Mas, com base nos seus valores, 0 nunca é ajustado de acordo com $min , porque nenhum valor para $sum_$n é menor que $sum_$n .

OUTPUT

$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

Na verdade, poderíamos colocar a coisa toda em uma única expansão de matemática e deixar o teste completo:

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

Isso define todas as variáveis apropriadamente para cada iteração, mas somente se expande para o valor de $min a cada vez. Imprime:

$min = 15665
$min = 15665
$min = 15665
$min = 15665
    
por 09.06.2015 / 21:48