¿Existe un programa estándar de Unix que devuelve un rango de números?


22

Estoy aprendiendo scripts de shell de un libro de texto desactualizado, y me parece que sería realmente útil tener un programa que solo devuelva una cadena de números delimitados por espacios como

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

Entonces, si está haciendo un script de shell, puede tener

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

¿Existe tal cosa o necesito escribirla yo mismo?


cuando dices "unix", ¿realmente te refieres a Linux? ¿O está realmente interesado en la portabilidad a otros sistemas (Solaris, BSD, ...)?
Glenn Jackman

2
s / range / seq - reemplace rangecon seqen su ejemplo. el separador predeterminado es nueva línea, para tener espacios:seq -s " " 10 20
n611x007

@naxa Ya sea que se trate de espacios o líneas nuevas, no importa en el forciclo, o incluso cualquier comando general que divide los argumentos, a menos que haya configurado el IFS de manera diferente.
slhck

1
Esta pregunta debería definir qué significa "programa unix estándar" para OP.
David Rivers

1
Como @DavidRivers ya comentó, debe indicar en el título y la pregunta en que se centra en las distribuciones de Linux. La respuesta que aceptó sugiere una herramienta que NO es un programa estándar de Unix. Faltan varios Unix seqya que POSIX no lo especifica.
jlliagre

Respuestas:


79

seq es parte de coreutils.

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

Salida:

1
3
5
7
9
11

Si proporciona solo 2 argumentos para seq, el incremento es 1:

$ seq 4 9
4
5
6
7
8
9

2
sedtambién tiene buenas opciones como -sestablecer el separador o -wcalificar el ancho. Y puede proporcionar un incremento: seq -w -s ", " 0 5 20resultados en 00, 05, 10, 15, 20 .
scai

2
@scai que querías decir seq?
Carlos Campderrós

@ CarlosCampderrós Por supuesto, desafortunadamente ya no puedo editar mi comentario.
scai

3
seq 10 20también podría ser un ejemplo simple que vale la pena agregar;)
Der Hochstapler

@scai que es increíble, aprendí algo nuevo hoy :) para ser honesto, creo que deberías agregar eso como una respuesta separada y más detallada.
Tim Groeneveld

33

¿Bastaría Bash?

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

Puedes hacer muchas cosas con la expansión de llaves . Bash 4 también admite rangos acolchados, por ejemplo {01..20}.

Tenga en cuenta que Bash no se considera portátil y no es una utilidad estándar de Unix. Aunque puede asumir con seguridad que está instalado en la mayoría de los Linux modernos, no use esto en un script que planee ejecutar en todo tipo de máquinas similares a Unix.


13
@Maksim: Aunque yo también prefiero esta expansión de llaves, también hay una típica Un * x herramienta (hacer muy poco, pero hacerlo así) para que: seq. El uso es como en el ejemplo: seq -s " " 10 20. El -sparámetro es necesario porque, por defecto, los valores están separados por \n.
mpy

Sí, Bash no es "estándar" dependiendo de qué tan estricto interpretes eso. Simplemente me resulta más fácil de manejar y no requiere una llamada adicional.
slhck

1
@mpy, tenga en cuenta que seqes una utilidad GNU, y por lo tanto no es un "programa estándar de Unix"
Glenn Jackman

55
@glennjackman Según developer.apple.com/library/Mac/documentation/Darwin/Reference/… ... "El comando seq apareció por primera vez en el Plan 9 de Bell Labs. Un comando seq apareció en NetBSD 3.0 y se transfirió a FreeBSD 9.0 . Este comando se basó en el comando del mismo nombre en el Plan 9 de Bell Labs y las utilidades principales de GNU. El comando GNU seq apareció por primera vez en la versión de utilidades de shell 1.13 ".
200_success

También tenga en cuenta que puede hacerlo for i in {001..010}; ... ; doney pondrá a cero el número a 3 dígitos.
VolatileDream

9

Si desea algo estrictamente portátil (es decir, que no se base en extensiones o comandos específicos de bash no especificados por POSIX)

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

1
¿No necesitas agregar /dev/nullo < /dev/nulla eso?
Scott,

1
@Scott No, esto no es necesario. El estándar POSIX ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ) especifica: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

Antes de 10.7 no había seqen Mac OS X, pero jot, debido a la herencia BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Ejemplo:

$ jot - 1 3
1
2
3

2

Usa un forbucle

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

2

Puede usar seq, o si no tiene eso, puede escribirlo usted mismo:

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

En aras de la exhaustividad aquí, algo que funcionará con algunas variantes antiguas de Unix (siempre que tengan instalado Perl). No muy elegante.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.