Gere duas sequências de números separadas por “|”

6

Estou usando o bash (CentOS 5) e procurando gerar essa saída (eu suponho que eu poderia usar seq ou echo juntos, talvez?):

1|1,
2|2,
3|3,
....
31|31,
32|32,
33|33,

Eu pesquisei seq exemplos por mais de duas horas e o mais próximo que posso chegar é:

echo {1..31}..{1..31} | tr ' ' '\n'

que quase me dá o que eu quero, mas atrapalha quando eu mudo o .. para | ou até mesmo "|").

Uma segunda geração de números que eu preciso é formatada da mesma maneira, mas para anos descendentes, ou seja:

2015|2015,
2014|2014,
...
1938|1938,
1937|1937,
1936|1936,

Já escrevi manualmente estas duas listas, mas adoraria qualquer entrada sobre como eu poderia ter feito isso a partir da linha de comando para o futuro necessidades e aprender ( seq ou echo , estou assumindo).

    
por James Gaul 23.12.2015 / 21:04

8 respostas

9

Os seguintes itens devem ser feitos:

seq 0 31 | awk '{ print $1"|"$1", " }'

no caso descendente:

seq 31 -1 0 | awk '{ print $1"|"$1", " }'

Estes usam awk para duplicar o número em cada linha, separados por um caractere de pipe.

Ou usando o bash puro (como sugerido por DopeGhoti em um comentário):

for n in {0..31}; do printf "%d|%d,\n" $n $n; done
for n in {31..0}; do printf "%d|%d,\n" $n $n; done
    
por 23.12.2015 / 21:09
10

Minhas reviravoltas:

  • puro awk

    awk 'BEGIN{for(;n<31;)print ++n"|"n","}'
    
  • printf + xargs

    printf '%s\n' {0..31} | xargs -I {} echo "{}|{},"
    
  • repeat loop em zsh

    n=0; repeat 32 echo "$n|$((n++)),"
    
por 23.12.2015 / 23:13
7

E por diversão com paste :

paste -d'|,' <(seq 31) <(seq 31) /dev/null
    
por 23.12.2015 / 22:45
6
seq 100|sed 's/.*/&|&,/'

... deve fazer isso bem ...

Com apenas um shell:

i=-1 x=31
while [ "$i" -lt "$x" ]
do    echo "$((i+=1))|$i,"
done
    
por 23.12.2015 / 21:28
6

A solução mais simples (em ksh93, bash, zsh):

printf '%s|%s,\n' {1..31}{,}             ### Ascending  sequence.
printf '%s|%s,\n' {2015..1936}{,}        ### Descending sequence.

Ou, se você precisar usar um loop:

i=0 x=31
while    (( i++ < x ))
do       echo "$i|$i,"
done
    
por 24.12.2015 / 03:10
4

Alguns complicados:

seq  -f %.0f 0.9 0.5 33.8 | paste -d '|,\n' - - /dev/null
seq  -f %.0f 2015.1 -0.5 1935.2 | paste -sd '|,\n' - - /dev/null

Observe que seq não é um comando padrão. POSIXly, se você quiser imprimir um número de seqüência, as melhores ferramentas são awk e bc . bc pode fazer aritmética de precisão arbitrária, mas é muito limitada quando se trata de formatar sua saída, então awk é uma solução mais óbvia aqui.

awk 'BEGIN{for(i=1;i<=33;i++) print i "|" i ","}'

Embora você possa usar bc como:

echo 'for (i=1;i<=33;i++) {i;i}' | bc | paste -d '|,\n' - - /dev/null
    
por 24.12.2015 / 01:20
3

Usando o perl, você pode fazer o loop seq e o print em um único processo:

perl -e 'for (1..31) {print "$_|$_,\n"}'
    
por 24.12.2015 / 01:30
1

Ele não responde estritamente à parte "da linha de comando", mas como você diz que digitou as listas manualmente, permita que eu apresente: A maneira fácil e rápida de digitar o seu listas, usando vim .

A versão longa

Abra vim digitando: vim na linha de comando.

Entre no modo de inserção pressionando i . Digite a primeira linha: 1|1, e pressione <Esc> para sair do modo de inserção.

Pressione q para começar a gravar uma macro e pressione x (arbitrariamente) para gravar a macro no registro "x".

Digite yy para copiar a linha atual e p para colá-la. Isso também colocará o cursor no início da linha recém-colada. Em seguida, digite <C-a> (Control-A) para incrementar o número sob o cursor.

Digite t, para mover o cursor para frente antes da próxima vírgula (que o coloca no segundo número da linha). Digite <C-a> novamente para incrementar esse número também.

Digite q para parar de gravar a macro.

Agora, tudo o que resta é reproduzir a macro quantas vezes quiser. Nós vamos dizer 15, apenas para demonstração. Digite 15@x e sua macro será repetida 15 vezes, então sua tela agora mostrará sua lista de 1 a 17. Então, se você quiser mais linhas, você pode simplesmente digitar, por exemplo, 500@x .

Se você tiver muitas linhas, digite a letra k para subir no arquivo e j para ir para baixo. Quando você está na primeira linha a ser excluída, você pode excluir de lá até o final do arquivo, digitando dG .

A versão resumida

Para gerar a lista de 1 a 31, abra vim digitando vim<Enter> no prompt de comando e, em seguida, pressione as seguintes teclas:

i1|1,<Esc>qxyyp<C-a>t,<C-a>q29@x

Estou totalmente familiarizado com seq , tr , echo e compreendo as várias outras respostas publicadas. É minha opinião considerada que a melhor ferramenta para este trabalho é vim , a menos que você realmente precise script a geração de texto.

    
por 30.12.2015 / 08:28