Czy istnieje standardowy program uniksowy, który zwraca zakres liczb?

22

Uczę się skryptowania powłoki z przestarzałego podręcznika i wydaje mi się, że przydałby się program, który po prostu zwraca ciąg liczb oddzielonych spacjami coś w rodzaju

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

Następnie, jeśli robisz skrypt powłoki, możesz go mieć

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

czy coś takiego istnieje, czy też muszę sam to napisać?

MOJA V
źródło
kiedy mówisz „unix”, czy naprawdę masz na myśli Linuksa? Czy naprawdę interesuje Cię przenośność na inne systemy (Solaris, BSD, ...)?
glenn jackman
2
s / zakres / SEK - wymień rangesię seqw swoim przykładzie. domyślnym separatorem jest nowa linia, aby mieć spacje:seq -s " " 10 20
n611x007
@naxa To, czy są to spacje, czy znaki nowej linii, nie ma znaczenia w forpętli - ani nawet w dowolnym ogólnym poleceniu, które dzieli argumenty - chyba że ustawisz IFS inaczej.
slhck
1
To pytanie powinno zdefiniować, co oznacza „standardowy program unixowy” dla OP.
David Rivers
1
Jak już komentował @DavidRivers, powinieneś podać w tytule i pytaniu, na czym koncentrujesz się w dystrybucji Linuksa. Odpowiedź, którą zaakceptowałeś, sugeruje narzędzie, które NIE jest standardowym programem uniksowym. Brakuje kilku uniksowych, seqponieważ nie jest to określone przez POSIX.
jlliagre

Odpowiedzi:

79

seq jest częścią coreutils.

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

Wydajność:

1
3
5
7
9
11

Jeśli podasz tylko 2 argumenty seq, przyrost wynosi 1:

$ seq 4 9
4
5
6
7
8
9
choroba
źródło
2
sedma również ładne opcje, takie jak -sustawić separator lub -wwyrównać szerokość. I możesz podać przyrost: seq -w -s ", " 0 5 20wyniki w 00, 05, 10, 15, 20 .
scai
2
@scai miałeś na myśli seq?
Carlos Campderrós
@ CarlosCampderrós Oczywiście niestety nie mogę już edytować mojego komentarza.
scai
3
seq 10 20warto też dodać prosty przykład;)
Der Hochstapler
@ scai, który jest niesamowity, nauczyłem się dziś czegoś nowego :) szczerze mówiąc, myślę, że powinieneś dodać to jako osobną, bardziej szczegółową odpowiedź!
Tim Groeneveld
33

Czy Bash wystarczy?

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

Możesz robić wiele rzeczy dzięki rozszerzaniu nawiasów klamrowych . Bash 4 obsługuje również wyściełane zakresy, np {01..20}.

Zauważ, że Bash nie jest uważany za przenośny i nie jest standardowym narzędziem uniksowym. Chociaż możesz bezpiecznie założyć, że jest on zainstalowany na większości nowoczesnych Linuksów, nie używaj tego w skrypcie, który planujesz uruchomić na wszelkiego rodzaju komputerach uniksowych.

slhck
źródło
13
@Maksim: Chociaż ja też wolę tę rozwijanie nawiasów, jest również typowym Un * x narzędzie (zrobić bardzo niewiele, ale robić to dobrze) za to: seq. Użycie jest jak w przykładzie: seq -s " " 10 20. Ten -sparametr jest konieczny, ponieważ domyślnie wartości są oddzielone \n.
mpy
Tak, Bash nie jest „standardowy” w zależności od tego, jak surowo to interpretujesz. Po prostu łatwiej mi się z tym obchodzi i nie wymaga dodatkowego połączenia.
slhck
1
@ mpy, zauważ, że seqjest to narzędzie GNU, a zatem nie jest to „standardowy program
unixowy
5
@glennjackman Według developer.apple.com/library/Mac/documentation/Darwin/Reference/ ... ... „Komenda seq pojawiła się po raz pierwszy w Planie 9 z Bell Labs. Komenda seq pojawiła się w NetBSD 3.0 i została przeniesiona do FreeBSD 9.0 To polecenie było oparte na poleceniu o tej samej nazwie w Planie 9 od Bell Labs i podstawowych narzędzi GNU. Polecenie GNU seq pojawiło się po raz pierwszy w wydaniu narzędzi powłoki 1.13. ”
200_sukces
Pamiętaj też, że możesz to zrobić, for i in {001..010}; ... ; donea liczba ta zostanie wyzerowana do 3 cyfr.
VolatileDream
9

Jeśli chcesz czegoś ściśle przenośnego (tj. Nie zależy ono od określonych rozszerzeń bash lub poleceń nieokreślonych przez POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'
jlliagre
źródło
1
Nie musisz tego dodawać /dev/nullczy dodawać < /dev/null?
Scott
1
@ Scott Nie, nie jest to konieczne. Standard POSIX ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ) określa: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

Przed 10.7 nie było seqsystemu Mac OS X, ale jotze względu na dziedzictwo BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Przykład:

$ jot - 1 3
1
2
3
miku
źródło
2

Użyj forpętli

for ((i = 10; i <= 20; ++i)); do
    printf '%d\n' "$i"
done
użytkownik27076
źródło
2

Możesz użyć seqlub, jeśli go nie masz, możesz napisać to sam:

#!/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 ; }

Stosowanie:

$ ./seq 3
1
2
3

Lub:

$ ./seq 3 7
3
4
5
6
7
StackedCrooked
źródło
1

Dla kompletności tutaj coś, co będzie działać z niektórymi starszymi wariantami Uniksa (o ile mają one zainstalowany perl). Niezbyt elegancki.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
reto
źródło