Comando seq: Gerando Sequências de Números

Comando seq: Gerando Sequências de Números

O que você vai conseguir fazer

  • Gerar sequências com início, fim e passo usando `seq`
  • Repetir tarefas sobre uma sequência com `for i in $(seq ...)`
  • Explicar o preenchimento com zeros do `-w` e quando preferir `seq` a `{1..10}`

Pré-requisitos (leia estes primeiro)

Vai Digitar de 1 Até 100 na Mão?

Lina: Senpai, preciso criar de test1.txt até test100.txt. Preciso mesmo digitar o comando 100 vezes?
Veterano Linny: Calma, isso seria doloroso. O comando seq constrói uma sequência como "1, 2, 3, ... 100" em um instante.
Veterano Linny: Combine com um loop e você cria todos os 100 arquivos em uma única linha.

As palavras usadas aqui (para não confundir depois)

  • Sequência: números que vêm um atrás do outro, como 1, 2, 3.
  • Argumento: um valor escrito depois do comando. Em seq 5, o 5 é o argumento.
  • Incremento: quanto somar a cada passo. "Passo" quer dizer o mesmo.
  • Loop: um jeito de repetir o mesmo trabalho. Aqui usamos o for.
  • Preenchimento com zeros: acrescentar zeros na frente para alinhar os dígitos, transformando 1 em 01.
  • Variável: uma caixa que guarda um valor por um tempo. Aqui a caixa i recebe os números um a um.
  • ShellUm programa interativo que interpreta os comandos digitados e os executa.: o programa do terminal que lê o que você digita e executa os comandos. "bash" é um dos nomes dele.

O Que Você Vai Aprender

  • Como gerar uma sequência de números (1, 2, 3, ...) com seq
  • Como definir o início, fim e incremento (passo)
  • Como combinar com um loop for para repetir tarefas
  • Como preencher com zeros usando -w e mudar o separador com -s
  • Quando usar seq vs a notação {1..10} do bash

1. O Que é o Comando seq?

Conclusão: seq imprime uma sequência de números, um por linha. seq 5 gera de 1 até 5.

Lina: O que "seq" significa?
Veterano Linny: É abreviação de sequence, ou sequência, que quer dizer valores em ordem.
Veterano Linny: O uso mais simples é passar um único número. Tente digitar seq 5.
$ seq 5
1
2
3
4
5
Lina: Os números de 1 a 5 apareceram em coluna.
Veterano Linny: Isso. Passe um número e ele imprime de 1 até esse número.
Veterano Linny: Um valor por linha é a parte importante. Alimente isso em um loop e vira uma tarefa repetida.

2. Como Mudo o Número Inicial?

Conclusão: Passe dois argumentos e significa seq INICIO FIM. seq 3 7 gera de 3 até 7.

Lina: E se eu quiser de 5 a 10 em vez de começar do 1?
Veterano Linny: Coloque dois números. seq 5 10 significa "5 até 10".
Veterano Linny: A quantidade de argumentos muda o significado. Essa é a parte interessante do seq.
$ seq 5 10
5
6
7
8
9
10

A quantidade de argumentos muda o significado

  • seq FIM --> 1 até FIM
  • seq INICIO FIM --> INICIO até FIM
  • seq INICIO PASSO FIM --> define um incremento (próxima seção)

3. Como Defino o Incremento (Passo)?

Conclusão: Passe três argumentos e significa seq INICIO PASSO FIM. seq 0 2 10 gera de 0 até 10 em passos de 2.

Lina: Quero imprimir números alternados, tipo "2, 4, 6, 8."
Veterano Linny: Coloque o incremento no meio. Ele diz quanto somar a cada passo.
Veterano Linny: seq 2 2 10 significa "2 até 10 em passos de 2".
$ seq 2 2 10
2
4
6
8
10
Lina: Posso contar de trás pra frente, de um número grande para um pequeno?
Veterano Linny: Sim. Deixe o incremento negativo. seq 5 -1 1 conta de trás para frente: "5, 4, 3, 2, 1".
$ seq 5 -1 1
5
4
3
2
1

Também funciona com decimais. seq 1 0.5 3 gera 1.0, 1.5, 2.0, 2.5, 3.0 em passos de 0.5 (inteiros são preenchidos com o mesmo número de casas decimais).

4. Como Uso uma Sequência em um Loop for?

Conclusão: Escreva for i in $(seq 1 5) para alimentar cada número gerado na variável i e repetir. Ótimo para criar arquivos numerados em massa.

Lina: Finalmente, o jeito de criar 100 arquivos!
Veterano Linny: Combinamos um loop for com o seq. A parte $(seq 1 5) é trocada pelo que o seq imprimiu.
Veterano Linny: Ou seja, vira 1 2 3 4 5. Cada valor entra em i e o corpo se repete.
$ for i in $(seq 1 5); do
>   touch "test${i}.txt"
> done
$ ls
test1.txt  test2.txt  test3.txt  test4.txt  test5.txt
Lina: Cinco arquivos apareceram de uma vez. Então, se eu mudar para 100...
Veterano Linny: Exatamente, basta usar seq 1 100. Um trabalho de 100 linhas sai em uma só.

4-1. Lina Tropeça: Esquecer o $( )

Limpe os arquivos que você acabou de criar antes de testar. Assim só os arquivos novos aparecem.

$ rm test1.txt test2.txt test3.txt test4.txt test5.txt
$ ls

Com o ls sem imprimir nada, tente de novo.

Lina: Senpai, achei que tinha feito igual, mas apareceu um arquivo com nome estranho.
$ for i in seq 1 5; do
>   touch "test${i}.txt"
> done
$ ls
test1.txt  test5.txt  testseq.txt
Lina: O que é testseq.txt? E eu esperava cinco arquivos, mas vieram três.
Veterano Linny: Faltou o $( ). Sem ele, o shell lê seq, 1 e 5 como três palavras comuns.
Lina: Então ele nem executa o seq como comando?
Veterano Linny: Isso. O i recebe seq, depois 1, depois 5. Dá nisso: testseq.txt, test1.txt e test5.txt, três arquivos.
Lina: Os nomes contam a história toda. Agora fez sentido.
Veterano Linny: O $( ) significa "execute o comando de dentro e troque pelo resultado". Sempre use ao percorrer uma sequência.

O seq ainda não existe no terminal virtual deste site. Teste os exemplos deste artigo no seu próprio Linux ou terminal.

Dá para limpar os arquivos que você acabou de criar. Sempre olhe os alvos com ls antes de apagar.

$ ls test*.txt
$ rm test1.txt test5.txt testseq.txt

Diferente de um ambiente gráfico, o rm não manda os arquivos para a lixeira. Eles somem na hora. Se isso deixa você nervoso, use o rm -i, que pergunta arquivo por arquivo.

Se você esquecer o $( ) em for i in $(seq ...) e escrever for i in seq 1 5, o loop itera sobre as três strings literais seq, 1 e 5. O $( ) que substitui um comando por sua saída é obrigatório.

5. Como Alinho os Dígitos (Preenchimento com Zeros)?

Conclusão: Adicione -w para preencher números com zeros à esquerda até o valor mais largo. file01, file02, ... file10 mantêm os dígitos alinhados para que a ordem de classificação fique correta.

Lina: Quando listei test1.txt até test100.txt com ls, eles sairam em uma ordem estranha: test1, test10, test100, test2...
Veterano Linny: Isso porque a quantidade de dígitos é diferente. O ls compara os nomes como texto, letra por letra da esquerda, então 10 vem antes de 2.
Veterano Linny: Use -w (width, largura) e ele preenche com zeros, como 001, 002, ... 100.
Lina: Com os dígitos alinhados, ordenar como texto mantém a ordem certa.
$ seq -w 1 10
01
02
03
04
05
06
07
08
09
10
Lina: Tudo ficou com dois dígitos agora.
Veterano Linny: O maior número aqui é 10, que tem dois dígitos. Todo o resto acompanha essa largura.
Veterano Linny: Vá até 100 e eles se alinham em três dígitos, de 001 a 100.

Combine com criação de arquivos assim:

for i in $(seq -w 1 100); do touch "log_${i}.txt"; done

Isso cria de log_001.txt até log_100.txt com dígitos alinhados.

6. Como Mudo o Separador ou Formato?

Conclusão: Use -s para mudar o separador de nova linha para vírgula, espaço, etc. Use -f para definir um formato no estilo printf.

Lina: E se eu quiser "1,2,3,4,5" em uma linha em vez de uma coluna?
Veterano Linny: Use o -s, que vem de separador. -s , junta tudo com vírgulas.
$ seq -s , 1 5
1,2,3,4,5
Lina: Agora ficou em uma linha. Posso usar espaço como separador também?
Veterano Linny: -s " " gera espaços.
Veterano Linny: E o -f permite colocar texto na frente do número ou definir a largura dos dígitos.
$ seq -f "page-%02g" 1 3
page-01
page-02
page-03

Em -f, %g representa um número. O 02 em %02g significa "2 dígitos, preenchido com zeros." Para preenchimento com zeros apenas, -w da seção anterior é mais simples, mas -f permite adicionar prefixos e casas decimais livremente.

7. Qual a Diferença do {1..10} do bash?

Conclusão: O bash também tem {1..10} para sequências. Para valores fixos, {1..10} é mais rápido. Quando o intervalo vem de uma variável, use seq.

Lina: Uma vez vi echo {1..5} imprimir uma sequência. Qual a diferença do seq?
Veterano Linny: Boa observação. {1..5} é a expansão de chaves do bash, e ela é mais rápida que o seq.
Veterano Linny: Mas tem um ponto fraco. Ela não expande quando você usa uma variável.
$ echo {1..5}
1 2 3 4 5
$ n=5
$ echo {1..$n}
{1..5}
Lina: Ué, {1..$n} não virou uma sequência; imprimiu o texto literal.
Veterano Linny: Exato. A expansão de chaves não funciona com variáveis.
Veterano Linny: Mas seq 1 $n respeita a variável. Por isso o seq brilha quando a contagem do loop vem de uma.
$ n=5
$ seq 1 $n
1
2
3
4
5

for i in $(seq 1 $n) expande toda a sequência na memória para números grandes. Para dezenas de milhares a milhões de iterações, o loop aritmético for ((i=1; i<=n; i++)) é mais eficiente. Para o intervalo cotidiano de dezenas a milhares, seq é suficiente.

8. Armadilhas Comuns e Correções

Conclusão: A maioria dos problemas vem de três coisas: leitura errada da quantidade de argumentos, esquecimento do $( ) e ordem de classificação quebrada por falta de preenchimento com zeros.

Sintoma Causa Correção
Um intervalo diferente do esperado Entendeu errado a quantidade de argumentos Verifique a ordem seq INICIO PASSO FIM
Loop itera sobre o texto seq 1 5 Esqueceu o $( ) Escreva for i in $(seq 1 5)
Arquivos se classificam em ordem errada Sem preenchimento com zeros Alinhe dígitos com seq -w
{1..$n} não é uma sequência Expansão de chaves ignora variáveis Use seq 1 $n
Saída é coluna, não linha Separador padrão é nova linha Mude com -s , ou -s " "

O que não fazer

  • Expandir um intervalo enorme de uma vez com $(seq ...) e esgotar a memória
  • Criar arquivos numerados sem preenchimento com zeros e depois sofrer com a ordem de classificação

9. Mini Exercícios: Tente Você Mesmo

Conclusão: Três exercícios -- definir um passo, preencher com zeros e combinar com um loop -- confirmam na prática como o seq funciona.

Lina: Entendi como funciona. Quero confirmar na prática.
Veterano Linny: Ótimo. Aqui vão três tarefas. Crie primeiro um diretórioUm local que organiza arquivos. É a mesma ideia da "pasta" do Windows ou macOS. de treino e trabalhe dentro dele.
$ mkdir -p ~/seq-practice && cd ~/seq-practice

Tarefa 1: Imprima números descendo de 10 para 1, diminuindo de 2 em 2.

Ver dica 1 (direcionamento)

Escreva três argumentos. Você quer descer, então o número do meio é negativo.

Ver dica 2 (nome do comando)

O comando é o seq. Os argumentos vão na ordem seq INICIO PASSO FIM.

Ver a resposta
$ seq 10 -2 1
10
8
6
4
2

O valor final é 1, mas o número depois do 2 seria 0, que fica abaixo de 1. Por isso ele para no 2.

Tarefa 2: Imprima de 1 a 12 com preenchimento de zeros em dois dígitos.

Ver dica 1 (direcionamento)

Existe uma opção para alinhar os dígitos. Ela apareceu na seção 5.

Ver dica 2 (nome do comando)

O comando é o seq. A opção que alinha os dígitos tem o nome de "width", largura.

Ver a resposta
$ seq -w 1 12
01
02
03
04
05
06
07
08
09
10
11
12

O maior número é 12, que tem dois dígitos, então o conjunto todo fica com dois dígitos.

Tarefa 3: Crie 12 arquivos de report_01.txt a report_12.txt em massa, com os dígitos alinhados.

Ver dica 1 (direcionamento)

Alimente a sequência da tarefa 2 em um loop e combine com o comando que cria arquivos.

Ver dica 2 (nome do comando)

Você precisa de um loop for e do touch. Veja na seção 4 como uma sequência é entregue a um loop.

Ver a resposta
$ for i in $(seq -w 1 12); do touch "report_${i}.txt"; done
$ ls report_*.txt | head -n 3
report_01.txt
report_02.txt
report_03.txt

Confira também quantos foram criados.

$ ls report_*.txt | wc -l
12

Quando terminar o treino, dá para remover o diretório inteiro. Olhe o conteúdo antes de apagar.

$ cd ~
$ ls ~/seq-practice
$ rm -r ~/seq-practice

O rm -r apaga o diretório junto com tudo que está dentro dele. Confirme que o caminhoUma sequência de texto que descreve a localização de um arquivo ou diretório. é mesmo ~/seq-practice antes de executar.

10. Revisão

Lina: Vou resumir. O sentido do seq muda com a quantidade de argumentos. Um é o fim, dois são início e fim, e três colocam o passo no meio.
Veterano Linny: Exato. Guarde isso e você sempre obtém o intervalo que queria.
Lina: Dentro de um loop, preciso do $( ). E o -w é o que alinha os nomes de arquivo.
Veterano Linny: Perfeito. E quando o intervalo vem de uma variável, use seq em vez de {1..10}.

Resumo de Hoje em 3 Linhas

  1. O sentido do seq muda com a quantidade de argumentos: seq FIM, seq INICIO FIM, seq INICIO PASSO FIM
  2. Dentro de um loop, inclua o $( ). Sem ele, a palavra seq é percorrida como texto
  3. Use -w para alinhar os dígitos e use seq no lugar de {1..10} quando o intervalo vier de uma variável

Resumo / Próximas Leituras