Existe-t-il un programme Unix standard qui renvoie une plage de nombres

22

J'apprends l'écriture de scripts shell à partir d'un manuel obsolète, et il me semble que ce serait vraiment utile d'avoir un programme qui retourne juste une chaîne de nombres délimités par des espaces quelque chose comme

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

Ensuite, si vous faites un script shell, vous pouvez avoir

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

une telle chose existe-t-elle ou dois-je l'écrire moi-même?

MON V
la source
quand vous dites "unix", voulez-vous vraiment dire Linux? Ou êtes-vous vraiment intéressé par la portabilité vers d'autres systèmes (Solaris, BSD, ...)?
glenn jackman
2
s / range / seq - remplacez rangepar seqdans votre exemple. le séparateur par défaut est newline, pour avoir des espaces:seq -s " " 10 20
n611x007
@naxa Que ce soit des espaces ou des sauts de ligne n'a pas d'importance dans la forboucle - ou même toute commande générale qui divise les arguments - sauf si vous avez défini l'IFS différemment.
slhck
1
Cette question devrait définir ce que signifie "programme Unix standard" pour OP.
David Rivers
1
Comme @DavidRivers l'a déjà commenté, vous devez indiquer dans le titre et la question que vous vous concentrez sur les distributions Linux. La réponse que vous avez acceptée suggère un outil qui n'est PAS un programme Unix standard. Plusieurs Unix font défaut seqcar il n'est pas spécifié par POSIX.
jlliagre

Réponses:

79

seq fait partie de coreutils.

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

Sortie:

1
3
5
7
9
11

Si vous ne fournissez que 2 arguments à seq, l'incrément est de 1:

$ seq 4 9
4
5
6
7
8
9
choroba
la source
2
seda également de belles options comme -srégler le séparateur ou -wqualifier la largeur. Et vous pouvez fournir un incrément: seq -w -s ", " 0 5 20résultats en 00, 05, 10, 15, 20 .
scai
2
@scai vous vouliez dire seq?
Carlos Campderrós
@ CarlosCampderrós Bien sûr, malheureusement, je ne peux plus modifier mon commentaire.
scai
3
seq 10 20pourrait aussi être un exemple simple à ajouter;)
Der Hochstapler
@scai c'est génial, j'ai appris quelque chose de nouveau aujourd'hui :) pour être honnête, je pense que vous devriez ajouter cela comme une réponse séparée et plus détaillée!
Tim Groeneveld,
33

Bash suffirait-il?

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

Vous pouvez faire beaucoup de choses avec l' expansion d'accolade . Bash 4 prend également en charge les plages rembourrées, par exemple {01..20}.

Notez que Bash n'est pas considéré comme portable et n'est pas un utilitaire Unix standard. Bien que vous puissiez supposer en toute sécurité qu'il est installé sur la plupart des Linux modernes, ne l'utilisez pas dans un script que vous prévoyez d'exécuter sur toutes sortes de machines de type Unix.

slhck
la source
13
@Maksim: Bien que je préfère aussi cette expansion des accolades, il y a aussi un typique Un * x outil (faire très peu, mais bien le faire) pour que: seq. L'utilisation est comme dans votre exemple: seq -s " " 10 20. Le -sparamètre est nécessaire, car par défaut, les valeurs sont séparées par \n.
mpy
Ouais, Bash n'est pas "standard" selon la façon dont vous interprétez cela. Je trouve cela plus facile à gérer et cela ne nécessite pas d'appel supplémentaire.
slhck
1
@mpy, notez qu'il seqs'agit d'un utilitaire GNU, et donc pas d'un "programme Unix standard"
glenn jackman
5
@glennjackman D'après developer.apple.com/library/Mac/documentation/Darwin/Reference/… ... "" La commande seq est apparue pour la première fois dans le Plan 9 de Bell Labs. Une commande seq est apparue dans NetBSD 3.0 et portée sur FreeBSD 9.0 . Cette commande était basée sur la commande du même nom dans le Plan 9 de Bell Labs et des utilitaires principaux GNU. La commande GNU seq est apparue pour la première fois dans la version 1.13 des utilitaires shell. "
200_success
Notez également que vous pouvez le faire for i in {001..010}; ... ; doneet qu'il mettra le numéro à 3 chiffres.
VolatileDream
9

Si vous voulez quelque chose de strictement portable (c'est-à-dire qui ne dépend pas d'extensions bash spécifiques ou de commandes non spécifiées par POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'
jlliagre
la source
1
N'avez-vous pas besoin d'ajouter /dev/nullou de < /dev/nullfaire cela?
Scott
1
@Scott Non, ce n'est pas nécessaire. La norme POSIX ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ) spécifie: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

Avant 10.7, il n'y en avait pas seqsur Mac OS X, mais jot, en raison de l'héritage BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Exemple:

$ jot - 1 3
1
2
3
miku
la source
2

Utilisez une forboucle

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

Vous pouvez utiliser seq, ou si vous ne l'avez pas, vous pouvez l'écrire vous-même:

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

Usage:

$ ./seq 3
1
2
3

Ou:

$ ./seq 3 7
3
4
5
6
7
StackedCrooked
la source
1

Par souci d'exhaustivité, voici quelque chose qui fonctionnera avec certaines anciennes versions d'Unix (tant qu'elles auront perl installé). Pas vraiment élégant.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
reto
la source