Bash-kertolasku ja summaus

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

Hei, tarvitsen yksinkertaistetun lausekkeen kolmannelle riville, ehkä sellaisen, joka tekee ei käytä komentojen korvaamista.

Kommentit

  • @Theophrastus: Kuten ehdotettiin, se toimii hyvin, mutta entä jos halusin käyttää lauseketta (()) .
  • Tämä on bash eikä C, joten poista kaikki ; – ellet kirjoita sitä yksiriviseksi.
  • Katso myös: unix.stackexchange.com/q/40786/117549
  • declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
  • Sitä paitsi: $(( ... )) on aritmeettinen laajennus, ei komentojen korvaaminen.

vastaus

Aritmeettisen laajennuksen käyttäminen:

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

Vanhentuneen expr -apuohjelman käyttäminen:

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

bc -l ( -l ei todellisuudessa tarvita tässä tapauksessa, koska matemaattisia funktioita ei käytetä):

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

bc -l: n käyttäminen rinnakkaisprosessi (se toimii kuin eräänlainen laskentapalvelu taustalla¹):

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" 

Tämä viimeinen näyttää (epäilemättä) puhtaammalta ryhmässä 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" 

¹ Tämä ratkaisi minulle ongelman kerran, jolloin minun piti käsitellä suuri määrä syötettä silmukka. Käsittely vaati joitain liukulaskelmia, mutta kutu bc muutaman kerran silmukassa osoittautui erittäin hitaaksi. Kyllä, olisin voinut ratkaista sen monilla muilla tavoilla, mutta kyllästyin …

Vastaa

Voit yksinkertaistaa:

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

vastaanottajalle:

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

Vastaa

Voit pakottaa laskutoimituksen let -komennolla.

let a="2*k+1" 

Huomaa, että emme tarvitse $k tässä rakenteessa; yksinkertainen k tekee työn.

Kommentit

  • Se epäonnistuu, jos ' sa-tiedosto a=2whateverk+1 on nykyisessä Pahempaa, jos ' sa-tiedosto nimeltä a=2+b[$(reboot)]k+1, kutsuu komentoa reboot . Paras on käyttää ((...)) täällä (((a = 2 * k + 1))) tai POSIX-syntaksia: a=$((2 * k + 1))
  • Voimme lainata sitä; let a="2*k+1" sen ratkaisemiseksi.

vastaus

Tarvitset todennäköisesti seuraavan aritmeettisen laajennuksen:

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

Itse asiassa sinun ei tarvitse käyttää muuttujaa:

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

Tai laskentamuuttuja voidaan siirtää kohtaan for ((…)) silmukka:

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

((…)) -silmukalle

Ja tällöin myös aritmeettinen laajennus voisi olla siirretty silmukan sisäpuolelle:

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

Tai, jos haluat saada kaikki taulukon arvot:

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

Ei kaavaa

Mutta todennäköisesti lyhyin tapa välttää aritmeettinen laajennus on lisätä muuttujaa kahdesti:

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

Tai vielä yksinkertaisempi, käytä vain seq:

seq 1 2 100 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *