it-swarm.com.de

Bash-Multiplikation und Addition

for k in {0..49};
do
a=$(($((2*$k))+1));
echo $a;
done

Hallo, ich brauche einen vereinfachten Ausdruck für die dritte Zeile, vielleicht einen, der keine Befehlssubstitution verwendet.

20
AVS

Verwenden der arithmetischen Erweiterung:

for (( k = 0; k < 50; ++k )); do
  a=$(( 2*k + 1 ))
  echo "$a"
done

Verwenden des veralteten Dienstprogramms expr:

for (( k = 0; k < 50; ++k )); do
  a=$( expr 2 '*' "$k" + 1 )
  echo "$a"
done

Verwenden von bc -l (-l wird in diesem Fall nicht benötigt, da keine mathematischen Funktionen verwendet werden):

for (( k = 0; k < 50; ++k )); do
  a=$( bc -l <<<"2*$k + 1" )
  echo "$a"
done

Verwenden von bc -l als Co-Prozess (es wirkt wie eine Art Berechnungsdienst im Hintergrund¹):

coproc bc -l

for (( k = 0; k < 50; ++k )); do
  printf "2*%d + 1\n" "$k" >&${COPROC[1]}
  read -u "${COPROC[0]}" a
  echo "$a"
done

kill "$COPROC_PID"

Das letzte sieht (wohl) sauberer in ksh93:

bc -l |&
bc_pid="$!"

for (( k = 0; k < 50; ++k )); do
  print -p "2*$k + 1"
  read -p a
  print "$a"
done

kill "$bc_pid"

¹ Dies löste ein Problem für mich, bei dem ich eine große Menge an Eingaben in einer Schleife verarbeiten musste. Die Verarbeitung erforderte einige Gleitkommaberechnungen, aber das mehrmalige Laichen von bc in der Schleife erwies sich als außerordentlich langsam. Ja, ich hätte es auf viele andere Arten lösen können, aber mir war langweilig ...

32
Kusalananda

Sie können vereinfachen:

a=$(($((2*$k))+1));

zu:

a=$((2*k+1))
14
Jeff Schaller

Mit dem Befehl let können Sie eine Berechnung erzwingen.

let a="2*k+1"

Beachten Sie, dass wir in dieser Struktur kein $k Benötigen. Ein einfaches k erledigt den Job.

5
Stephen Harris

Die arithmetische Erweiterung, die Sie wahrscheinlich benötigen, ist folgende:

a=$(( 1+2*k ))

Tatsächlich müssen Sie keine Variable verwenden:

for k in {0..49}; do
    echo "$(( 1 + 2*k ))"
done

Oder die Zählvariable könnte in eine for ((…)) - Schleife verschoben werden:

for (( k=0;k<50;k++ )); do
    a=$(( 1+2*k ))
    printf '%s\n' "$a"
done

for ((…)) Schleife

In diesem Fall könnte die arithmetische Erweiterung auch in die for-Schleife verschoben werden:

for (( k=0 ; a=1+2*k , k<50 ;  k++)); do
    printf '%s\n' "$a"
done

Oder um alle Werte in einem Array abzurufen:

for (( k=0 ; a[k]=1+2*k , k<49 ;  k++ )); do :; done
printf '%s\n' "${a[@]}"

Keine Formel

Der wahrscheinlich kürzeste Weg, um eine arithmetische Erweiterung zu vermeiden, besteht darin, eine Variable zweimal zu erhöhen:

for (( k=0,a=1 ; k<50 ;  k++,a++,a++ )); do
    printf '%s\n' "$a"
done

Oder, noch einfacher, verwenden Sie einfach seq:

seq 1 2 100
2
user79743