Como faço para construir uma lista com números como este?

7

Como faço para construir uma lista como esta:

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

Onde eu corro command 15 ou algo assim. Ou, se eu especificar 100 , ele seria composto por 100 números ou 10000 , e assim seria, mas 10000 números.

Deve haver cinco números em cada linha (conforme visto acima).

    
por DisplayName 05.11.2014 / 17:10

8 respostas

15

você simplesmente faz

seq 1 n | xargs -n 5 echo

n sendo o número que você deseja alcançar

Se o seu SO tiver bash mas não seq, aqui está uma alternativa (thx to @cuonglm e @jimmyj para seus comentários)

echo {1..n} | xargs -n5

(você pode ter que ser cuidadoso ao atingir muito alto número com esse, dependendo do SO e da versão bash, e se o bash realmente tentou expandir primeiro ou nesse caso é inteligente o suficiente para se alimentam pouco a pouco sem tentar encaixar o 1.2.n inteiro como uma string na memória e alimentar isso para ecoar ...)

E graças a cuonglm e StephaneChazelas, eu adiciono uma alternativa que é muito, muito menos CPU pesada do que a minha primeira solução xargs (em que xargs chama / bin / echo, em vez de poder usar o builtin do shell, cada 5 números ) (é provavelmente semelhante ao segundo, onde o xargs não invoca o eco):

printf '%s %s %s %s %s\n' {1..n}

Essa segunda e terceira solução é diferente da primeira em que o shell tem que expandir primeiro 1.n, antes que printf (ou xargs) possa começar a imprimir, se não me engano ... então começa mais tarde (especialmente if n é grande) ... E poderia atingir alguns limites (tamanho da linha ou memória, dependendo da implementação e do sistema operacional) se n for muito grande.

    
por 05.11.2014 / 17:16
8

% purocoreutils:

$ seq 15 | paste - - - - - 
1   2   3   4   5
6   7   8   9   10
11  12  13  14  15

Perl puro:

$ perl -e '@a=1..15; while($i<=$#a){print "@a[$i..$i+4]\n";$i+=5}'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

GNU grep (descaradamente roubado de @ 1_CR ):

$ echo {1..15} | grep -oP '(\d+ ){4}\d+'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

Se você não se importa em liderar 0s:

$ echo {01..15} | fold -sw 16
01 02 03 04 05 
06 07 08 09 10 
11 12 13 14 15

E se você fizer isso:

$ echo {01..15} | fold -sw 16 | sed 's/0\([1-9]\) / /g'
1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15

Qualquer um destes pode ser feito em uma função que leva um número como entrada e imprime a lista correspondente. Por exemplo,

printnums(){
 seq $1 | paste - - - - - 
}

Você pode então executar

$ printnums 30
1   2   3   4   5
6   7   8   9   10
11  12  13  14  15
16  17  18  19  20
21  22  23  24  25
26  27  28  29  30
    
por 05.11.2014 / 19:18
5

Com printf e expansão de contraventores :

printf '%s %s %s %s %s\n' {1..15}
    
por 05.11.2014 / 17:29
4

com zsh :

$ print -aC5 {1..15}
1   2   3   4   5
6   7   8   9   10
11  12  13  14  15

$ autoload zargs # if not in ~/.zshrc
$ zargs -n 5 {1..15} -- echo
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

$ printf '%s %s %s %s %s\n' {1..15}
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

(este último também funciona em versões recentes do ksh93 ou bash).

    
por 05.11.2014 / 17:33
2

usando looping:

for x in {1..15};do echo -n "$x ";if [ $(($x%5)) -eq 0 ];then echo ; fi done

saída:

1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15 
    
por 05.11.2014 / 17:36
2

Com awk , você pode dizer:

seq 15 | awk 'ORS=NR%5?FS:RS'

Ele retorna:

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

Basicamente, ele altera o separador de registro de saída (separador de linha) por um separador de campo (espaço, por padrão) ou um separador de registro (nova linha, como padrão). Portanto, se o número de linhas for múltiplo de 5 , uma nova linha será adicionada; caso contrário, um espaço.

Eu escrevi uma explicação mais ampla em uma pergunta semelhante: bash / sed / awk / etc remove todas as outras novas linhas .

    
por 06.11.2014 / 11:12
1

Você pode usar seq , tr e sed :

seq 15 | tr '\n' ' ' | sed 's/\([0-9]* [0-9]* [0-9]* [0-9]* [0-9]* \)/\
/g'

Ou como uma combinação otimizada das respostas de Olivier, Benoit e eu (em seus comentários):

seq 15 | xargs -n 5
    
por 05.11.2014 / 17:17
1

Todas as soluções elegantes foram tomadas ... então com o GNU awk e bash

echo {1..15} | awk -v RS='[[:space:]]' '{ORS=NR % numcols?RT:"\n"; print}' numcols=5
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

ou com o GNU grep

echo {1..15} | grep -oE '([[:digit:]]+[[:blank:]]+){4}[[:digit:]]+'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
    
por 05.11.2014 / 19:00