Existe um programa unix padrão que retorna um intervalo de números

22

Estou aprendendo scripts de shell de um livro desatualizado, e parece-me realmente útil ter um programa que apenas retorna uma sequência de números delimitados por espaços como

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

Então, se você estiver executando um script de shell, poderá ter

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

existe tal coisa, ou eu mesmo preciso escrever?

MEU V
fonte
quando você diz "unix", você realmente quer dizer Linux? Ou você está realmente interessado em portabilidade para outros sistemas (Solaris, BSD, ...)?
Glenn Jackman
2
s / range / seq - substitua rangepor seqno seu exemplo. separador padrão é de nova linha, ter espaços:seq -s " " 10 20
n611x007
@naxa Sejam espaços ou novas linhas, não importa no forloop - ou mesmo qualquer comando geral que divida argumentos - a menos que você defina o IFS de maneira diferente.
Slhck 28/05
1
Esta pergunta deve definir o que "programa unix padrão" significa para OP.
David Rivers
1
Como o @DavidRivers já comentou, você deve declarar no título e a pergunta que seu foco está nas distribuições Linux. A resposta que você aceitou sugere uma ferramenta que NÃO é um programa Unix padrão. Faltam vários Unix, seqpois não é especificado pelo POSIX.
Jlliagre

Respostas:

79

seq faz parte do coreutils.

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

Saída:

1
3
5
7
9
11

Se você fornecer apenas 2 argumentos seq, o incremento será 1:

$ seq 4 9
4
5
6
7
8
9
choroba
fonte
2
sedtambém possui boas opções, como -sdefinir o separador ou -wqualificar a largura. E você pode fornecer um incremento: seq -w -s ", " 0 5 20resulta em 00, 05, 10, 15, 20 .
Scai 28/05
2
@scai você quis dizer seq?
Carlos Campderrós
@ CarlosCampderrós Claro, infelizmente não posso mais editar meu comentário.
Scai 28/05
3
seq 10 20pode também ser um exemplo simples pena acrescentar;)
Der Hochstapler
@ SCAI que é incrível, eu aprendi algo novo hoje :) para ser honesto, acho que você deve adicionar isso como uma resposta separada e mais detalhada!
Tim Groeneveld
33

Bash seria suficiente?

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

Você pode fazer muitas coisas com a expansão de chaves . O Bash 4 também suporta faixas acolchoadas, por exemplo {01..20}.

Observe que o Bash não é considerado portátil e não é um utilitário Unix padrão. Embora você possa assumir com segurança que ele está instalado na maioria dos Linux modernos, não use isso em um script que planeja executar em todos os tipos de máquinas semelhantes ao Unix.

slhck
fonte
13
@Maksim: Embora eu também preferem esta expansão cinta, há também um típico * x ferramenta Un (fazer muito pouco, mas fazer isso também) para que: seq. O uso é como no seu exemplo: seq -s " " 10 20. O -sparâmetro é necessário porque, por padrão, os valores são separados por \n.
Mpy
Sim, o Bash não é "padrão", dependendo de quão rigoroso você interpreta isso. Apenas acho mais fácil de manusear e não exige uma ligação extra.
Slhck 28/05
1
@mpy, nota que seqé um utilitário GNU, e, portanto, não um "programa padrão UNIX"
Glenn Jackman
5
@glennjackman De acordo com developer.apple.com/library/Mac/documentation/Darwin/Reference/… ... "O comando seq apareceu pela primeira vez no Plano 9 do Bell Labs. Um comando seq apareceu no NetBSD 3.0 e foi portado para o FreeBSD 9.0 Este comando foi baseado no comando com o mesmo nome no Plano 9 do Bell Labs e dos utilitários principais do GNU. O comando GNU seq apareceu pela primeira vez na versão 1.13 dos utilitários de shell. "
200_success
Observe também que você pode fazer for i in {001..010}; ... ; donee o número será preenchido com zero para 3 dígitos.
VolatileDream
9

Se você deseja algo estritamente portátil (ou seja, que não dependa de extensões bash específicas ou comandos não especificados pelo POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'
jlliagre
fonte
1
Você não precisa adicionar /dev/nullou < /dev/nulla isso?
28513 Scott
1
@ Scott Não, isso não é necessário. O padrão 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 seqda versão 10.7, não havia no Mac OS X, mas jotdevido à herança do BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Exemplo:

$ jot - 1 3
1
2
3
miku
fonte
2

Use um forloop

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

Você pode usar seq ou, se não tiver, pode escrever você mesmo:

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

Ou:

$ ./seq 3 7
3
4
5
6
7
StackedCrooked
fonte
1

Para fins de completude, aqui algo que funcionará com algumas variantes mais antigas do Unix (desde que tenham o perl instalado). Não é realmente elegante.

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