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ć?


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

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.


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}'

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


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.