Como usar o sed para substituir todas as ocorrências de um padrão menos um caso?

Como usar o sed para substituir todas as ocorrências de um padrão menos um caso?

Eu tenho um arquivo temporário gerado por um cron job a cada meia hora que gera uma saída como esta:

---- kind=<data> field=<value> humankind=<data> kind=<data> field=<value> humankind=<data> kind=<data> field=<value> humankind=<data>

Quero formatá-lo para que fique assim:

---- kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>

Eu tentei as seguintes expressões sed:

sed -r 's|\s(kind=)|\n\1|g' /path/to/file

Mas então a saída se parece com:

----                                         <------ The first line should be here
kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>
kind=<data> field=<value> humankind=<data>

Usando esta expressão:

sed -r 's|[^-]{4} (kind=)|\n\1|g' /path/to/file

Gera a saída que desejo, mas com comportamento estranho:

---- kind=<data> field=<value> humankind=<incomplete data>
kind=<data> field=<value> humankind=<incomplete data>
kind=<data> field=<value> humankind=<incomplete data>

Por alguma razão, o último campo (que contém parte do padrão usado na expressão sed) está imprimindo apenas os dois primeiros caracteres de 'dados incompletos'.

O que estou fazendo de errado?

Responder1

O problema sed -r 's|\s(kind=)|\n\1|g' /path/to/fileé que você insere uma nova linha para todas as ocorrências de 'tipo', incluindo a primeira, para obter uma nova linha extra depois de ----. Em vez disso, tente

sed -E 's|\s(kind=)|\n\1|2g' /path/to/file

pois irá pular a primeira partida.

O segundo falha porque corresponde a 4 caracteres antes de 'kind' e isso faz parte dos seus dados (que devem ter 6 caracteres)!

informação relacionada