Moltiplicazione e addizione di Bash

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

Ciao, ho bisogno di unespressione semplificata per la terza riga, forse una che funziona non utilizzare la sostituzione del comando.

Commenti

  • @ Theophrastus: come suggerito funziona bene, ma se volessi usare expr invece di (()) .
  • Questo è bash e non C, quindi rimuovi tutto ; – a meno che non lo scrivi in una riga singolare.
  • Vedi anche: unix.stackexchange.com/q/40786/117549
  • declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
  • A parte: $(( ... )) è lespansione aritmetica non la sostituzione del comando.

Risposta

Utilizzo dellespansione aritmetica:

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

Utilizzando lantica utilità expr:

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

Utilizzando bc -l ( -l non effettivamente necessario in questo caso poiché non vengono utilizzate funzioni matematiche):

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

utilizzando bc -l come co-processo (agisce come una sorta di servizio di calcolo in background¹):

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" 

Questultimo sembra (probabilmente) più pulito 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" 

¹ Questo ha risolto un problema per me una volta in cui dovevo elaborare una grande quantità di input in un ciclo continuo. Lelaborazione ha richiesto alcuni calcoli in virgola mobile, ma la generazione di bc alcune volte nel ciclo si è rivelata estremamente lenta. Sì, avrei potuto risolverlo in molti altri modi, ma ero annoiato …

Risposta

Puoi semplificare:

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

a:

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

Risposta

Puoi utilizzare il comando let per forzare un calcolo.

let a="2*k+1" 

Nota che non abbiamo bisogno di $k in questa struttura; un semplice k farà il lavoro.

Commenti

  • Non riesce se ' un file chiamato a=2whateverk+1 nella corrente Peggio ancora, se cè ' un file chiamato a=2+b[$(reboot)]k+1, che chiama il comando reboot . La cosa migliore è utilizzare ((...)) qui (((a = 2 * k + 1))) o la sintassi POSIX: a=$((2 * k + 1))
  • Possiamo citarla; let a="2*k+1" per risolverlo.

Risposta

Lespansione aritmetica di cui probabilmente hai bisogno è questa:

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

In effetti, non è necessario utilizzare una variabile:

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

Oppure la variabile di conteggio potrebbe essere spostata in un for ((…)) loop:

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

for ((…)) loop

E, in tal caso, lespansione aritmetica potrebbe anche essere spostato allinterno del ciclo for:

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

Oppure, per ottenere tutti i valori in un array:

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

Nessuna formula

Ma probabilmente il modo più breve per evitare qualsiasi espansione aritmetica è incrementare due volte una variabile:

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

Oppure, ancora più semplice, usa semplicemente seq:

seq 1 2 100 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *