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
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 chiamatoa=2+b[$(reboot)]k+1
, che chiama il comandoreboot
. 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
bash
e nonC
, quindi rimuovi tutto;
– a meno che non lo scrivi in una riga singolare.declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
$(( ... ))
è lespansione aritmetica non la sostituzione del comando.