Bash vermenigvuldigen en optellen

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

Hallo, ik heb een vereenvoudigde uitdrukking nodig voor de derde regel, misschien een die dat wel doet gebruik geen opdrachtvervanging.

Opmerkingen

  • @Theophrastus: Zoals gesuggereerd werkt het prima, maar wat als ik expr zou willen gebruiken in plaats van (()) .
  • Dit is bash en niet C, dus verwijder alle ; – tenzij je het op een enkele regel schrijft.
  • Zie ook: unix.stackexchange.com/q/40786/117549
  • declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
  • Terzijde: $(( ... )) is rekenkundige uitbreiding, geen opdrachtvervanging.

Antwoord

Rekenkundige uitbreiding gebruiken:

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

Met het verouderde expr hulpprogramma:

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

Met bc -l ( -l niet echt nodig in dit geval omdat er geen wiskundige functies worden gebruikt):

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

bc -l gebruiken als een co-proces (het werkt als een soort rekenservice op de achtergrond¹):

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" 

Die laatste ziet er (aantoonbaar) schoner uit 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" 

¹ Dit loste eens een probleem voor mij op waarbij ik een grote hoeveelheid invoer moest verwerken in een lus. De verwerking vereiste enkele drijvende-kommaberekeningen, maar het een paar keer uitzetten van bc in de lus bleek buitengewoon traag te zijn. Ja, ik had het op veel andere manieren kunnen oplossen, maar ik verveelde me …

Antwoord

Je kunt het vereenvoudigen:

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

aan:

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

Antwoord

U kunt het let commando gebruiken om een berekening af te dwingen.

let a="2*k+1" 

Merk op dat we in deze structuur geen $k nodig hebben; een simpele k zal het werk doen.

Opmerkingen

  • Dat mislukt als er ' een bestand met de naam a=2whateverk+1 in de huidige directory. Erger nog, als er ' een bestand met de naam a=2+b[$(reboot)]k+1 is, wordt het reboot commando aangeroepen . Het beste is om ((...)) hier (((a = 2 * k + 1))) te gebruiken, of de POSIX-syntaxis: a=$((2 * k + 1))
  • We kunnen het citeren; let a="2*k+1" om dat op te lossen.

Antwoord

De rekenkundige uitbreiding die u waarschijnlijk nodig heeft is deze:

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

In feite hoeft u geen variabele te gebruiken:

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

Of de telvariabele kan worden verplaatst naar een for ((…)) loop:

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

for ((…)) loop

En in dat geval zou de rekenkundige uitbreiding ook kunnen zijn verplaatst naar binnen de for-lus:

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

Of, om alle waarden in een array te krijgen:

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

Geen formule

Maar waarschijnlijk is de kortste manier om rekenkundige uitbreiding te vermijden, een variabele twee keer te verhogen:

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

Of, nog eenvoudiger, gebruik seq:

seq 1 2 100 

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *