Esiste un programma unix standard che restituisce un intervallo di numeri


22

Sto imparando gli script di shell da un libro di testo obsoleto, e mi sembra che sarebbe davvero utile avere un programma che restituisca solo una stringa di numeri delimitati da spazi qualcosa come

$ range 10 20
10 11 12 13 14 15 16 17 18 19 20

Quindi, se stai facendo uno script di shell puoi avere

for i in `range 10 20`; do some stuff with numbers in that range;done

esiste una cosa del genere o devo scriverla da solo?


quando dici "unix", intendi davvero Linux? Oppure sei veramente interessato alla portabilità ad altri sistemi (Solaris, BSD, ...)?
Glenn Jackman,

2
s / range / seq - sostituisci rangecon seqnel tuo esempio. il separatore predefinito è newline, per avere spazi:seq -s " " 10 20
n611x007,

@naxa Che si tratti di spazi o di nuove righe, non importa nel forciclo, o anche di qualsiasi comando generale che divide argomenti, a meno che tu non abbia impostato l'IFS in modo diverso.
slhck,

1
Questa domanda dovrebbe definire cosa significa "programma unix standard" per OP.
David Rivers,

1
Come già commentato @DavidRivers, dovresti indicare nel titolo e la domanda su cui ti concentri sulle distribuzioni Linux. La risposta che hai accettato suggerisce uno strumento che NON è un programma Unix standard. Diversi Unix mancano seqin quanto non specificato da POSIX.
jlliagre,

Risposte:


79

seq fa parte di coreutils.

for i in $( seq 1 2 11 ) ; do echo $i ; done

Produzione:

1
3
5
7
9
11

Se si forniscono solo 2 argomenti a seq, l'incremento è 1:

$ seq 4 9
4
5
6
7
8
9

2
sedha anche delle belle opzioni come -simpostare il separatore o -wqualificare la larghezza. E puoi fornire un incremento: seq -w -s ", " 0 5 20risultati in 00, 05, 10, 15, 20 .
scai,

2
@scai intendevi seq?
Carlos Campderrós,

@ CarlosCampderrós Certo, sfortunatamente non posso più modificare il mio commento.
scai,

3
seq 10 20potrebbe anche essere un semplice esempio che vale la pena aggiungere;)
Der Hochstapler,

@scai è fantastico, ho imparato qualcosa di nuovo oggi :) a dire il vero, penso che dovresti aggiungerlo come risposta separata e più dettagliata!
Tim Groeneveld,

33

Basterebbe Bash?

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

Puoi fare molte cose con espansione del controvento . Bash 4 supporta anche intervalli imbottiti, ad es {01..20}.

Si noti che Bash non è considerato portatile e non un'utilità Unix standard. Anche se puoi tranquillamente supporre che sia installato sulla maggior parte dei Linux moderni, non usarlo in uno script che prevedi di eseguire su tutti i tipi di macchine simili a Unix.


13
@Maksim: Anche se io preferisco questo anche espansione delle parentesi graffe, c'è anche una tipica Un * x strumento (fare ben poco, ma farlo bene) per questo: seq. L'utilizzo è come nel tuo esempio: seq -s " " 10 20. Il -sparametro è necessario, perché per impostazione predefinita i valori sono separati da \n.
mpy,

Sì, Bash non è "standard" a seconda di quanto rigorosamente lo interpreti. Trovo che sia più facile da gestire e non richiede una chiamata extra.
Slhck,

1
@mpy, nota che seqè un'utilità GNU, e quindi non un "programma unix standard"
glenn jackman,

5
@glennjackman Secondo developer.apple.com/library/Mac/documentation/Darwin/Reference/… ... "Il comando seq è apparso per la prima volta in Plan 9 da Bell Labs. Un comando seq è apparso in NetBSD 3.0 e portato su FreeBSD 9.0 . Questo comando era basato sul comando con lo stesso nome in Plan 9 di Bell Labs e le utility di base GNU. Il comando seq GNU è apparso per la prima volta nella versione 1.13 delle utility di shell. "
200_successo,

Nota anche che puoi farlo for i in {001..010}; ... ; donee azzererà il numero a 3 cifre.
VolatileDream,

9

Se vuoi qualcosa di strettamente portatile (cioè che non si basa su specifiche estensioni bash o comandi non specificati da POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'

1
Non hai bisogno di aggiungere /dev/nullo < /dev/nulla quello?
Scott,

1
@Scott No, questo non è necessario. Lo standard POSIX ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ) specifica:If the awk program contains no actions and no patterns, but is otherwise a valid awk program, standard input and any file operands shall not be read and awk shall exit with a return status of zero.
jlliagre,

6

Prima del 10.7 non c'era seqsu Mac OS X, ma jot, a causa dell'eredità di BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Esempio:

$ jot - 1 3
1
2
3

2

Usa un forciclo

for ((i = 10; i <= 20; ++i)); do
    printf '%d\n' "$i"
done

2

Puoi usare seq, o se non lo hai, puoi scriverlo tu stesso:

#!/bin/bash
[ $# -ge 1 ] || { echo "Usage: seq Number [ Number ]" 1>&2 ; exit 1; }
[ $# -eq 1 ] && { [ $1 -gt 1 ] && ./seq $(($1 - 1)) ; echo $1 ; }
[ $# -eq 2 ] && { [ $(($2 - $1)) -gt 0 ] && ./seq $1 $(($2 - 1)) ; echo $2 ; }

Uso:

$ ./seq 3
1
2
3

O:

$ ./seq 3 7
3
4
5
6
7

1

Per completezza qui qualcosa che funzionerà con alcune vecchie versioni di Unix (purché abbiano installato perl). Non molto elegante.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
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.