Bash çarpma ve toplama


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

Merhaba, üçüncü satır için basitleştirilmiş bir ifadeye ihtiyacım var, belki de komut ikamesi kullanmayan biri.


@Theophrastus: Önerildiği gibi iyi çalışıyor ama (()) yerine ifade kullanmak istersem ne olur.
AVS

Bu bashve değil C, ;tek bir satıra yazmadıkça hepsini kaldırın .
ott--


declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
Cyrus

1
Bir yana: $(( ... ))aritmetik genişleme komut yerine değil.
dave_thompson_085

Yanıtlar:


28

Aritmetik genişletmeyi kullanma:

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

Antika expryardımcı programı kullanma :

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

Kullanarak bc -l( -laslında matematik işlevi kullanılmadığı için bu durumda gerekli değildir):

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

bc -lİşbirliği olarak kullanmak (arka planda bir tür hesaplama hizmeti gibi davranır¹):

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"

Sonuncusu (tartışmasız) daha temiz görünüyor 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"

¹ Bu, bir döngüde büyük miktarda girdi işlemem gereken bir kez benim için bir sorunu çözdü. İşleme bazı kayan nokta hesaplamaları gerektiriyordu, ancak bcdöngüde birkaç kez ortaya çıkmanın son derece yavaş olduğu kanıtlandı. Evet, başka birçok yolla çözebilirdim, ama sıkıldım ...



5

letBir hesaplamayı zorlamak için komutu kullanabilirsiniz .

let a="2*k+1"

$kBu yapıda ihtiyacımız olmadığını unutmayın ; basit bir kiş yapacak.


4
a=2whateverk+1Geçerli dizinde çağrılan bir dosya varsa bu başarısız olur . Daha kötüsü, adlı bir dosya varsa a=2+b[$(reboot)]k+1, rebootkomutu çağırır . En iyisi ((...))burada ( ((a = 2 * k + 1))) veya POSIX sözdizimini kullanmaktır:a=$((2 * k + 1))
Stéphane Chazelas

Alıntı yapabiliriz; let a="2*k+1"bunu çözmek için.
Stephen Harris

2

Muhtemelen ihtiyacınız olan aritmetik genişleme şudur:

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

Aslında, bir değişken kullanmanıza gerek yoktur:

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

Veya sayma değişkeni bir for ((…))döngüye taşınabilir :

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

döngü için

Ve bu durumda, aritmetik genişleme for döngüsünün içine de taşınabilir:

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

Veya, bir dizideki tüm değerleri almak için:

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

Formül yok

Ancak, herhangi bir aritmetik genişlemeyi önlemenin en kısa yolu, bir değişkeni iki kez artırmaktır:

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

Veya daha da basit, sadece seq kullanın:

seq 1 2 100
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.