encurtar linhas longas em um arquivo de log

5

Eu mantenho um arquivo de log da saída de um programa. O problema é que, às vezes, ocorrem erros ao despejar linhas muito longas de dados ascii de 7 bits (binários codificados) que não me importo de manter. Essas linhas podem ter 200 KB ou mais antes de chegarem a uma nova linha.

O que pode ser uma maneira curta e pipetável, por exemplo. com sed para alterar apenas linhas com mais de 250 caracteres, mantendo apenas os primeiros 80 e os últimos 40 caracteres dessa linha, possivelmente substituindo o meio por apenas um _ ?

    
por Marcos 18.06.2012 / 19:30

4 respostas

12

No sed, todos os comandos podem ser prefixados por uma condição que indica para quais linhas aplicar o comando. Um tipo comum de condição é um padrão de pesquisa. O padrão de pesquisa /.\{250\}/ corresponde a linhas com mais de 250 caracteres. Para essas linhas, combine os primeiros 80 caracteres e os últimos 40 e substitua a linha inteira pelo prefixo __ e o sufixo.

sed -e '/.\{250\}/ s/^\(.\{80\}\).*\(.\{40\}\)$/__/'

Você pode até mesmo organizar o padrão do comando de substituição para corresponder apenas a linhas suficientemente longas.

sed -e 's/^\(.\{80\}\).\{130,\}\(.\{40\}\)$//'
    
por 19.06.2012 / 01:30
7

Eu não sei sed well, então minha solução está em awk:

awk 'length>250{len=length;$0=substr($0,1,80) "_" substr($0,len-40+1)};1' file
    
por 18.06.2012 / 19:58
2

Aqui está um comando do awk que fará isso:

awk 'len=length{if(len>250){print substr($0,0,80),"__",substr($0,len-40,len)}else{print $0}}' data.txt

Explicação :

Se a linha tiver mais de 250 caracteres, imprima os primeiros 80 caracteres, seguidos por uma sequência de _ __ e, em seguida, os últimos 40 caracteres.

Se a linha tiver menos de 250 caracteres, basta imprimir a linha original.

    
por 18.06.2012 / 19:58
2

Existe uma maneira de extrair os primeiros 80 e os últimos 40 caracteres de uma linha com sed , no entanto sed não tem 'if statements', então não há nenhuma maneira diretamente no sed para testar a string comprimento e, em seguida, executar uma operação nele.

Capturar os primeiros 80 e os últimos 40 caracteres de todas linhas pode ser feito com | sed -e 's/^\(.\{80\}\).*\(.\{40\}\)/\_/' .

sed -i -e 's/^\(.\{80\}\).*\(.\{40\}\)/\_/' logfile

executará modificação no local do seu arquivo, mas está limitado a operar em todas as linhas.

    
por 18.06.2012 / 21:59