mesclar blocos de quatro linhas em uma linha [duplicado]

1

Estou preso a isso.

eu tenho um arquivo de entrada que parece

16:20:03 Buy
DRIP
AMEX
500 13,51 USD
16:05:10 Sell
SQ
NYSE
100 36,32 USD
15:48:52 Sell
NXTD
Nasdaq
500 4,99 USD
15:48:52 Sell
NXTD
Nasdaq
500 4,99 USD
15:46:07 Buy
SOXL
AMEX
50 147,7209 USD
15:40:20 Buy
TEUM
AMEX
1 700 1,36 USD
15:40:19 Buy
TEUM
AMEX
300 1,36 USD

meu objetivo é obter cada registro de quatro linhas em uma linha, por exemplo

16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD

Eu sei que cada registro é de quatro linhas. Eu também sei que cada registro começa com (é separado por) uma hora no formato hh: mm: ss

Eu tentei vários comandos do awk especificando RS / FS OFS / ORS Eu tentei diferentes variantes de sed como

sed 'N;N;s/\n/ /'

O awk imprime apenas o primeiro registro. O sed não consegue obter todos os elementos na mesma linha

Eu posso postar exemplos mais específicos do que tentei. Parece realmente simples. Alguém que pode me dar uma dica?

Se você conhece uma solução mais fácil em outro idioma, fique à vontade para elaborar

    
por HenrikJson 21.12.2017 / 23:28

4 respostas

3

Usando colar

$ paste -d' ' - - - - <file
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD

Usando sed

$ sed 'N;N;N; s/\n/ /g' file
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD

Usando o awk

$ awk '{line=line " " $0} NR%4==0{print substr(line,2); line=""}' file
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD
    
por 21.12.2017 / 23:31
3

Solução Perl

perl -pe 's/\n/ / if $. % 4' < file
  • -p lê a linha de entrada por linha, processa e imprime de volta para o saída;
  • $. contém o número da linha de entrada
  • s/\n/ / substitui uma nova linha por um espaço
  • % é o operador de módulo, então a condição é "se o número da linha não é divisível por quatro"
por 21.12.2017 / 23:33
1

A solução mais fácil é provavelmente com ex , a forma não visual de vi (que é especificado pelo POSIX ).

printf '%s\n' 'g/^/j4' x | ex input.txt

Equivalente:

printf 'g/^/j4\nx\n' | ex input.txt

Explicação:

O comando printf apenas produz a seguinte saída, que são comandos para ex :

g/^/j4
x

O comando x significa salvar e sair. Substitua por %p se você quiser imprimir o arquivo modificado na saída padrão e não salvar as alterações (boas para testes).

g é o comando global e recebe um regex (nesse caso, /^/ , que naturalmente corresponderá a cada linha) e, em seguida, um comando. O comando é executado em todas as linhas correspondidas pela expressão regular.

j4 significa unir a linha atual com as três linhas a seguir. Espaços são colocados entre quando se juntam.

Você também pode acionar vi e digitar 4J e, em seguida, j para descer uma linha e digitar . e, em seguida, j para descer uma linha e . Mas com a forma ex , qualquer linha restante no final do arquivo (menos de quatro) será unida; com o comando J em vi , não é esse o caso.

    
por 21.12.2017 / 23:47
0
$ awk '{printf $0 (NR%4?" ":"\n")}' file1
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD
    
por 22.12.2017 / 00:13

Tags