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
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 naama=2+b[$(reboot)]k+1
is, wordt hetreboot
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
bash
en nietC
, dus verwijder alle;
– tenzij je het op een enkele regel schrijft.declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
$(( ... ))
is rekenkundige uitbreiding, geen opdrachtvervanging.