Club juntos N linha consecutiva no shell?

3

Digamos que eu tenha um arquivo de texto neste formato

field1a
field2a
field3a
field1b
field2b
field3b

Eu quero club 3 (ou no caso geral N) linhas consecutivas, como eu faço isso com sed ou outro utilitário de linha de comando no bash shell?

saída esperada

field1a:field2a:field3a
field1b:field2b:field3b
    
por Dude 06.11.2014 / 12:31

5 respostas

10

 paste -sd '::\n' file

Ou:

 awk '{ORS=NR%3?":":"\n";print}' < file

(note a diferença se o número de registros na entrada não for um múltiplo de 3).

    
por 06.11.2014 / 12:36
3

com paste :

paste -d: - - - <file

Mesclar um arquivo colando os dados em três colunas ( - - - ) usando um separador de dois-pontos:

Com o Perl:

perl -pe 'if($.%3){s/\n/:/;}' file

com a opção -p faz impressão padrão. Tudo o que fazemos aqui é, se o número da linha for de 3 ( %3 ), substitua o caractere de nova linha ( \n ) por dois pontos ( : ).

Com xargs e awk :

xargs -L 3 < file | awk '$1=$1' OFS=:

O argumento -L em xargs informa quantas linhas ingressar. E awk coloca o separador de campos de saída (OFS) de Space (por padrão) para separador de dois pontos ( : ).

com awk :

awk 'NR%3{printf "%s:",$0;next}{print;}' file

Imprima o módulo de 3 linhas usando printf (sem nova linha) com dois pontos, e faça uma impressão normal para a próxima linha usando print (o que coloca a nova linha por padrão).

referência

    
por 06.11.2014 / 15:48
2

Para formatação de saída, você pode usar printf

IFS='
'       # split on sequences of newline characters
set -f # disable globbing
printf "%s:%s:%s\n" $(cat file)

(note que ele pula linhas vazias).

Ou sed (se você quiser)

sed '$!N;$!N;s/\n/:/g' file
    
por 06.11.2014 / 13:42
2

com sed :

sed '$!N;$!N;y/\n/:/'

Embora eu ache que é menos geral do que N linhas do que deveria ser. Se o número de linhas que você deseja sempre estará no final do campo, então:

sed '$q;N;/1.$/!s/\(..*\)\(\n\)/:/;//P;D
' <<\INPUT 
field1a
field1b
field2b
field1c
INPUT

OUTPUT

field1a
field1b:field2b
field1c

... que empilha linhas após uma que termina com 1 e depois com qualquer caractere até encontrar outra também terminando com 1 e outra coisa.

Funcionaria para qualquer número de campos, mas você pode querer fazer ...

sed '.../[^0-9]1.$/!...'

... se você entrar em vários dígitos.

    
por 06.11.2014 / 21:52
0

Se eu tiver apenas algumas centenas ou menos linhas, ou se o número de campos por grupo variar, então o vi funcionará muito bem para mim.

No vi, se eu quiser juntar as duas linhas atuais e seguintes (3 linhas de texto ao todo), então ...

    3J

Neste ponto, meu cursor está na linha concatenada, então desço para o próximo ...

    j

Eu faço a mesma modificação em relação à linha atual usando o ponto ...

    .

E mais uma vez ...

    j
    .

Oops! Esse último grupo tinha 4 linhas, não 3. Eu desfiz a última modificação ...

    u

e faça de novo, certo agora ...

    4J

Próximo! ...

    j

... e assim por diante.

Note que, se você pretende fazer isso para o seu carregamento de banco de dados de 360 milhões de campos, ou se seus campos consecutivos forem geralmente 3, com alguns grupos de 4 e talvez um grupo raro de 5 ou 6, então você provavelmente quer suportar a sintaxe arcana de sair do circuito, condicionando seus dados por etapas e talvez escrevendo um programa para testá-lo e alertá-lo sobre erros.

Mas se é um trabalho pequeno e único, eu suporto apenas alguns minutos de tédio e uso vi.

    
por 08.01.2017 / 21:33