Bash multiplicare și adunare

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

Bună, am nevoie de o expresie simplificată pentru a treia linie, poate una care nu utilizați substituirea comenzii.

Comentarii

  • @ Theophrastus: Așa cum am sugerat, funcționează bine, dar dacă aș vrea să folosesc expr în loc de (()) .
  • Acesta este bash și nu C, deci eliminați toate ; – dacă nu îl scrieți într-o linie singulară.
  • Vedeți și: unix.stackexchange.com/q/40786/117549
  • declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
  • În afară de: $(( ... )) este extinderea aritmetică nu substituirea comenzii.

Răspuns

Utilizarea expansiunii aritmetice:

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

Utilizarea utilitarului expr vechi:

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

Utilizarea bc -l -l nu este de fapt necesar în acest caz deoarece nu sunt utilizate funcții matematice):

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

Utilizarea bc -l ca coprocesare (acționează ca un fel de serviciu de calcul în fundal¹):

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" 

Ultimul pare (probabil) mai curat în 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" 

¹ Aceasta a rezolvat o problemă pentru mine odată cu care aveam nevoie să procesez o cantitate mare de intrare în O buclă. Prelucrarea a necesitat câteva calcule în virgulă mobilă, dar reproducerea bc de câteva ori în buclă s-a dovedit a fi extrem de lentă. Da, aș fi putut să o rezolv în multe alte moduri, dar m-am plictisit …

Răspunde

Poți simplifica:

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

la:

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

Răspuns

Puteți utiliza comanda let pentru a forța un calcul.

let a="2*k+1" 

Rețineți că nu avem nevoie de $k în această structură; un simplu k va face treaba.

Comentarii

  • Acest lucru nu reușește dacă există un fișier ' numit a=2whateverk+1 director. Mai rău, dacă există ' un fișier numit a=2+b[$(reboot)]k+1, care apelează comanda reboot Cel mai bine este să folosiți ((...)) aici (((a = 2 * k + 1))) sau sintaxa POSIX: a=$((2 * k + 1))
  • O putem cita; let a="2*k+1" pentru a rezolva acest lucru.

Răspuns

Extinderea aritmetică de care probabil aveți nevoie este aceasta:

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

De fapt, nu este necesar să utilizați o variabilă:

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

Sau variabila de numărare ar putea fi mutată într-o for ((…)) loop:

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

pentru ((…)) loop

Și, în acest caz, extinderea aritmetică ar putea fi, de asemenea, mutat în interiorul buclei for:

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

Sau, pentru a obține toate valorile dintr-o matrice:

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

Fără formulă

Dar probabil cea mai scurtă modalitate de a evita orice expansiune aritmetică este creșterea unei variabile de două ori:

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

Sau, și mai simplu, folosiți doar sec:

seq 1 2 100 

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *