Come produrre un intervallo con il passaggio n in bash? (genera una sequenza di numeri con incrementi)


143

Il modo di iterare su un intervallo in bash è

for i in {0..10}; do echo $i; done

Quale sarebbe la sintassi per iterare sulla sequenza con un passaggio? Dire, vorrei ottenere solo il numero pari nell'esempio sopra.


Numeri pari, moltiplicare i per 2.: P
Joey Robert,

la moltiplicazione è piuttosto brutta, dovrei dire
SilentGhost,

2
@Omnifarious Non ne sarei così sicuro. OS X arriva ancora con 3.2, per esempio. Direi che il ciclo in stile C dovrebbe essere accettato.
Eli Korvigo,

Risposte:


195

Farei

for i in `seq 0 2 10`; do echo $i; done

(anche se ovviamente seq 0 2 10produrrà lo stesso output da solo).

Si noti che seqconsente numeri in virgola mobile (ad es. seq .5 .25 3.5) Ma l'espansione del controvento di bash consente solo numeri interi.


4
Immagino che il downvote sia dovuto alla tua risposta generica a "sh" e non specifica a "bash". L'approccio puro di Bash {begin end step} ha prestazioni leggermente migliori. Il vecchio metodo "seq" è utile su sistemi di memoria più vecchi o più piccoli, come busybox. Ho votato positivamente sia la tua risposta che quella di TheBonsai. :)
Scott Prive,

6
Preferisci $ (...) ai backquotes. I backquotes non si annidano in modo sano.
Onnipotente il

seq 1000000 1000010 fa solo float, in realtà - non c'è modo di farlo fare numeri interi! L'espansione del controvento funziona.
hmijail piange le dimissioni il

112

L'espansione del controvento di Bash 4 ha una funzione di passaggio:

for {0..10..2}; do
  ..
done

Non importa se Bash 2/3 (stile C per loop, vedi le risposte sopra) o Bash 4, preferirei qualsiasi cosa al comando 'seq'.


1
e btw, sai se bash4 è di default su qualsiasi SO principale?
SilentGhost,

3
Bash4 non è ancora mainstream, no. Perché non seq? Bene, diciamolo con le parole del bot nel canale IRC #bash: "seq (1) è un comando esterno altamente non standard usato per contare fino a 10 in sciocchi howtos di Linux".
TheBonsai

la mia comprensione è che seq è una parte di coreutils. che cosa non è standard al riguardo? argomenti? Grazie per l'aiuto.
SilentGhost,

4
Questi argomenti possono o meno contare per te: * ci sono abbastanza sistemi senza GNU coreutils (ma installato Bash) * crei un processo esterno non necessario * ti affidi all'idea che tutto 'seq' fa quello che fa il tuo 'seq' * è non standardizzato dall'ISO
TheBonsai l'

3
@becko Se il passaggio è memorizzato nella variabile i, non è possibile farlo for {0..10..${i}}.. fallisce.
Nehal J Wani,

72

Pure Bash, senza un processo aggiuntivo:

for (( COUNTER=0; COUNTER<=10; COUNTER+=2 )); do
    echo $COUNTER
done

10
+1 Perché il passaggio può essere sostituito anche da una variabile.
Nehal J Wani,

1
Penso che questo sia davvero ciò che la maggior parte delle persone probabilmente desidera: un modo semplice per fare un ciclo con un valore di passo prescritto. Sembra più semplice di tutte le risposte basate su seq, ed è una sintassi più chiara dell'espansione della parentesi graffa di Bash4 e sembra che consentirebbe le variabili (non l'ho provato, ma la sintassi lo suggerisce sicuramente).
tobylaroni,

Funziona in Bash 3, a differenza della risposta di @ TheBonsai.
Srcerer,

Risolve anche la variabile, ((i = "$ first"; i <= "$ last"; i + = "$ step")). Non così facile con parentesi graffe e seq.
Blaa_Thor il

20
#!/bin/bash
for i in $(seq 1 2 10)
do
   echo "skip by 2 value $i"
done

seq è un comando Linux. Questo non sarà disponibile su Mac OS X o FreeBSD.
Dereckson,

5
FWIW seq è disponibile nel mio OS X Mavericks 10.9.1 standard
Mark Setchell,

Ho provato qualche altra sintassi, ma questo è l'unico che funziona per il mio su un po 'CentOS. @z - mi ha salvato la giornata: D
m3nda

3
> seq 4
1
2
3
4

> seq 2 5
2
3
4
5

> seq 4 2 12
4
6
8
10
12

> seq -w 4 2 12
04
06
08
10
12

> seq -s, 4 2 12
4,6,8,10,12
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.