símbolos de substituição para quebra de linha (\ n) e adicionar as três primeiras colunas a partir do início da linha

2

Eu tenho um arquivo de log com texto:

Jan 10 09:56:17  1484207777.225918 GET "8.8.8.8" "curl/7.27.0" #0121484207777.226639 GET "8.8.8.9" "curl/7.21.0" #0121484207777.226639 GET "8.8.5.9" "curl/7.22.0"
Jan 10 19:59:17  1484207777.225456 GET "8.8.6.8" "curl/7.24.0" #0121484207777.226639 GET "8.8.5.9" "curl/7.21.0" #0121484207777.226425 GET "8.8.5.9" "curl/7.22.0"

Eu preciso substituir os símbolos "#" por quebra de linha (\ n) e adicionar data / hora a partir desta linha.

Eu preciso do resultado:

Jan 10 09:56:17  1484207777.225918 GET "8.8.8.8" "curl/7.27.0" 
Jan 10 09:56:17  0121484207777.226639 GET "8.8.8.9" "curl/7.21.0" 
Jan 10 09:56:17  0121484207777.226639 GET "8.8.5.9" "curl/7.22.0"
Jan 10 19:59:17  1484207777.225456 GET "8.8.6.8" "curl/7.24.0" 
Jan 10 19:59:17  0121484207777.226639 GET "8.8.5.9" "curl/7.21.0" 
Jan 10 19:59:17  0121484207777.226425 GET "8.8.5.9" "curl/7.22.0"

Eu tentei com sed, mas sem resultado.

for a in $(cat logs)

do

b=$(cat logs | awk '{print $1, $2, $3}')

echo "$a" | sed 's/#/\n"$b"/g'

done

Você pode me ajudar por favor com essa tarefa?

    
por Oleksii 12.01.2017 / 15:49

2 respostas

4

Se o seu campo de data é seguido por vários espaços, enquanto os outros campos são separados por único espaços, como mostrado no seu exemplo, você poderia fazer

$ awk -F'  +' '{n = split($2,a,"#"); for (i=1;i<=n;i++) print $1,a[i]}' log
Jan 10 09:56:17 1484207777.225918 GET "8.8.8.8" "curl/7.27.0"
Jan 10 09:56:17 0121484207777.226639 GET "8.8.8.9" "curl/7.21.0"
Jan 10 09:56:17 0121484207777.226639 GET "8.8.5.9" "curl/7.22.0"
Jan 10 19:59:17 1484207777.225456 GET "8.8.6.8" "curl/7.24.0"
Jan 10 19:59:17 0121484207777.226639 GET "8.8.5.9" "curl/7.21.0"
Jan 10 19:59:17 0121484207777.226425 GET "8.8.5.9" "curl/7.22.0"

Em geral, você pode substituir o # da seguinte forma

$ awk '{gsub(/#/, sprintf("\n%s %s %s ", $1, $2, $3))} 1' log
Jan 10 09:56:17  1484207777.225918 GET "8.8.8.8" "curl/7.27.0"
Jan 10 09:56:17 0121484207777.226639 GET "8.8.8.9" "curl/7.21.0"
Jan 10 09:56:17 0121484207777.226639 GET "8.8.5.9" "curl/7.22.0"
Jan 10 19:59:17  1484207777.225456 GET "8.8.6.8" "curl/7.24.0"
Jan 10 19:59:17 0121484207777.226639 GET "8.8.5.9" "curl/7.21.0"
Jan 10 19:59:17 0121484207777.226425 GET "8.8.5.9" "curl/7.22.0"
    
por steeldriver 12.01.2017 / 16:24
0

Um pequeno script python pode fazer o trabalho:

#!/usr/bin/env python
from __future__ import print_function
import sys

for line in sys.stdin:
    timestamp = "\n" + " ".join(line.strip().split()[0:3])
    print(line.replace('#',timestamp),end="")

E demonstração de como funciona:

$ ./break_lines.py < input.txt                                                                                           
Jan 10 09:56:17  1484207777.225918 GET "8.8.8.8" "curl/7.27.0" 
Jan 10 09:56:170121484207777.226639 GET "8.8.8.9" "curl/7.21.0" 
Jan 10 09:56:170121484207777.226639 GET "8.8.5.9" "curl/7.22.0"
Jan 10 19:59:17  1484207777.225456 GET "8.8.6.8" "curl/7.24.0" 
Jan 10 19:59:170121484207777.226639 GET "8.8.5.9" "curl/7.21.0" 
Jan 10 19:59:170121484207777.226425 GET "8.8.5.9" "curl/7.22.0"

A explicação de como isso funciona é simples - nós dividimos a linha em palavras e pegamos as 3 primeiras palavras e as unimos em uma string que tem uma nova linha anexada na frente depois de simplesmente substituir # por essa nova string. e viola!

    
por Sergiy Kolodyazhnyy 14.01.2017 / 14:09