Bash-multiplikation och tillägg

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

Hej, jag behöver ett förenklat uttryck för tredje raden, kanske en som gör använd inte kommandosubstitution.

Kommentarer

  • @Theophrastus: Som föreslås fungerar det bra men vad händer om jag vill använda expr istället för (()) .
  • Det här är bash och inte C, så ta bort alla ; – om du inte skriver det i en enstaka rad.
  • Se även: unix.stackexchange.com/q/40786/117549
  • declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
  • Bortsett från: $(( ... )) är aritmetisk expansion inte kommandosubstitution.

Svar

Med hjälp av aritmetisk expansion:

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

Med det föråldrade expr -verktyget:

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

Användning av bc -l ( -l behövs egentligen inte i det här fallet eftersom inga matematiska funktioner används):

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

Använd bc -l som samprocess (det fungerar som en slags beräkningstjänst i bakgrunden¹):

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 sista ser (utan tvekan) renare ut 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" 

¹ Detta löste ett problem för mig en gång där jag behövde bearbeta en stor mängd input i en runda. Bearbetningen krävde beräkningar av flytande punkter, men att leka bc några gånger i slingan visade sig vara extremt långsam. Ja, jag kunde ha löst det på många andra sätt, men jag var uttråkad …

Svar

Du kan förenkla:

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

till:

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

Svar

Du kan använda kommandot let för att tvinga fram en beräkning.

let a="2*k+1" 

Observera att vi inte behöver $k i den här strukturen. En enkel k gör jobbet.

Kommentarer

  • Det misslyckas om det finns ' en fil som heter a=2whateverk+1 Värre, om det finns ' en fil som heter a=2+b[$(reboot)]k+1, som kallar kommandot reboot Det bästa är att använda ((...)) här (((a = 2 * k + 1))), eller POSIX-syntaxen: a=$((2 * k + 1))
  • Vi kan citera det; let a="2*k+1" för att lösa det.

Svar

Den aritmetiska expansionen du förmodligen behöver är den här:

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

I själva verket behöver du inte använda en variabel:

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

Eller så kan räknevariabeln flyttas till en for ((…)) loop:

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

för ((…)) loop

Och i så fall kan den aritmetiska expansionen också vara flyttade till inuti for-slingan:

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

Eller för att få alla värden i en matris:

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

Ingen formel

Men förmodligen är det kortaste sättet att undvika aritmetisk expansion att öka en variabel två gånger:

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

Eller, ännu enklare, använd bara seq:

seq 1 2 100 

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *