Divide o texto em uma ordem específica usando a string comum “Message”

3

Eu tenho um arquivo de texto com o seguinte conteúdo

$ cat foo.txt

some text 
[email protected]
8903457923
2018-02-09 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message
some text 
[email protected]
8903457923
2018-02-05 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message

Eu gostaria de obter o seguinte resultado

$ cat foo.txt

some text  [email protected]  8903457923  2018-02-09 07:12 (Asia/Kolkata)  again some text over her  some more text again  Message

some text [email protected]  8903457923  2018-02-05 07:12 (Asia/Kolkata) again some text over here  some more text again  Message

Acho que posso conseguir isso usando tr e pegando "Message" como uma string comum. Mas não tenho certeza de como implementar isso.

    
por smc 20.06.2018 / 16:53

5 respostas

6

Se a linha atual não for "Mensagem", anexe a linha à lista, associada a OFS; quando vir "Mensagem", imprima a lista atual (unida por OFS com a atual linha "Mensagem"):

awk '/^Message$/ { print t OFS $0 ORS; t=""; } !/^Message$/ { t=(t ? t OFS $0 : $0) }' < foo.txt

A parte t=(t ? t OFS $0 : $0) é um operador ternário; ele verifica se t está vazio; se for, basta atribuir a linha atual a ela; caso contrário, acrescente o valor atual ao OFS seguido da linha atual.

Saída:

some text  [email protected] 8903457923 2018-02-09 07:12 (Asia/Kolkata) again some text over here some more text again Message

some text  [email protected] 8903457923 2018-02-05 07:12 (Asia/Kolkata) again some text over here some more text again Message
    
por 20.06.2018 / 17:06
5

um pouco mais fácil com o AWK:

awk 'BEGIN { ORS=RS="Message\n" } gsub("\n"," ")' ./in.txt

    
por 20.06.2018 / 17:30
2

Usando tr e sed :

tr '\n' '\t' <foo.txt  | sed -e $'s/Message\\t/Message\\n\\n/g'

Isso converterá todas as novas linhas em guias e adicionará duas novas linhas após cada ocorrência de Message

    
por 20.06.2018 / 17:17
0

Você pode tentar este sed

sed ':A;/Message/!{N;bA};y/\n/ /;$!G' foo.txt

Obter linhas no espaço padrão até ver Mensagem.
Substituir cada nova linha pelo espaço em branco.
Adicione uma linha em branco somente se não for a última.

    
por 20.06.2018 / 17:25
0

O método mais simples e direto é:

 perl -lpe '$\ = /^Message$/ ? "\n\n" : " "' foo.txt

ou usando awk seria:

 awk 'ORS = /^Message$/ ? RS RS : " "'

Slurp o arquivo, -0777 , em seguida, o arquivo inteiro é uma cadeia grande em que o regex /(.*?)^(Message\n)/msg é operado. A regex examina o fragmento mais curto que fica na linha Message e armazena o fragmento em $1 e a linha nessage em $2 . O chunk compreende novas linhas que são substituídas globalmente por espaço e o resultado dessa transformação tr/\n/ /r é entregue em print . O loop while continua, desde que as linhas da mensagem + sejam encontradas.

perl -ln -0777e 'print $1 =~ tr/\n/ /r, $2 while /(.*?)^(Message\n)/msg' foo.txt

Poderíamos usar a ferramenta sed para realizar este trabalho, conforme mostrado aqui:

sed -e '
    $!N;G;s/\n/ /                ;# put 2 lines in pattern space
    / Message\n$/b               ;# one message block has been found
    s/\(.*\)\(.\)//;D        ;# go back to read the next line into pattern space
' foo.txt
    
por 21.06.2018 / 12:50