for k in {0..49}; do a=$(($((2*$k))+1)); echo $a; done
Hej, jeg har brug for et forenklet udtryk til tredje linje, måske en der gør ikke bruge kommandosubstitution.
Kommentarer
Svar
Brug af aritmetisk udvidelse:
for (( k = 0; k < 50; ++k )); do a=$(( 2*k + 1 )) echo "$a" done
Brug af det forældede expr -hjælpeprogram:
for (( k = 0; k < 50; ++k )); do a=$( expr 2 "*" "$k" + 1 ) echo "$a" done
Brug af bc -l ( -l faktisk ikke nødvendigt i dette tilfælde, da der ikke bruges matematiske funktioner):
for (( k = 0; k < 50; ++k )); do a=$( bc -l <<<"2*$k + 1" ) echo "$a" done
Brug af bc -l som samproces (det fungerer som en slags beregningstjeneste i baggrunden¹):
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"
Den sidste ser (uden tvivl) renere ud i 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"
¹ Dette løste et problem for mig en gang, hvor jeg havde brug for at behandle en stor mængde input i en løkke. Behandlingen krævede nogle flydende beregninger, men gydning bc et par gange i sløjfen viste sig at være meget langsom. Ja, jeg kunne have løst det på mange andre måder, men jeg keder mig …
Svar
Du kan forenkle:
a=$(($((2*$k))+1));
til:
a=$((2*k+1))
Svar
Du kan bruge kommandoen let til at tvinge en beregning.
let a="2*k+1"
Bemærk, at vi ikke har brug for $k i denne struktur. En simpel k gør jobbet.
Kommentarer
- Det mislykkes, hvis der ' en fil kaldet
a=2whateverk+1i den aktuelle Værre, hvis der ' en fil kaldeta=2+b[$(reboot)]k+1, der kalder kommandoenrebootDet bedste er at bruge((...))her (((a = 2 * k + 1))) eller POSIX-syntaksen:a=$((2 * k + 1)) - Vi kan citere det;
let a="2*k+1"for at løse det.
Svar
Den aritmetiske udvidelse, du sandsynligvis har brug for, er denne:
a=$(( 1+2*k ))
Faktisk behøver du ikke bruge en variabel:
for k in {0..49}; do echo "$(( 1 + 2*k ))" done
Eller tællingsvariablen kan flyttes til en for ((…)) loop:
for (( k=0;k<50;k++ )); do a=$(( 1+2*k )) printf "%s\n" "$a" done
for ((…)) loop
Og i så fald kan den aritmetiske udvidelse også være flyttet til inde i for-sløjfen:
for (( k=0 ; a=1+2*k , k<50 ; k++)); do printf "%s\n" "$a" done
Eller for at få alle værdier i et array:
for (( k=0 ; a[k]=1+2*k , k<49 ; k++ )); do :; done printf "%s\n" "${a[@]}"
Ingen formel
Men sandsynligvis er den korteste måde at undgå enhver aritmetisk udvidelse på at øge en variabel to gange:
for (( k=0,a=1 ; k<50 ; k++,a++,a++ )); do printf "%s\n" "$a" done
Eller endnu enklere, brug bare seq:
seq 1 2 100
bashog ikkeC, så fjern alle;– medmindre du skriver det i en entallig linje.declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done$(( ... ))er aritmetisk udvidelse ikke kommandosubstitution.