Mudança na estrutura do arquivo de log do Linux, comportamento anormal (?) sed

2

Ok, então tentei conseguir isso

0x0000:  4500 0044 68f7 4000 4011 25c7 8083 d0bf  E..Dh.@.@.%.....
0x0010:  8083 da24 85b1 15b3 0030 1e8b 3132 3033  ...$.....0..1203
0x0020:  3132 2e37 3836 3036 2c20 332c 2020 2030  12.78606,.3,...0
0x0030:  2e31 3533 2c20 2d30 2e31 3533 2c20 2039  .153,.-0.153,..9
0x0040:  2e39 3630                                .960

0x0000:  4500 0044 68f8 4000 4011 25c6 8083 d0bf  E..Dh.@.@.%.....
0x0010:  8083 da24 85b1 15b3 0030 148f 3132 3033  ...$.....0..1203
0x0020:  3132 2e38 3336 3131 2c20 332c 2020 2d30  12.83611,.3,..-0
0x0030:  2e31 3533 2c20 2d30 2e34 3630 2c20 2039  .153,.-0.460,..9
0x0040:  2e39 3630                                .960

0x0000:  4500 0044 68f9 4000 4011 25c5 8083 d0bf  E..Dh.@.@.%.....
0x0010:  8083 da24 85b1 15b3 0030 1b80 3132 3033  ...$.....0..1203
0x0020:  3132 2e38 3836 3135 2c20 332c 2020 2d30  12.88615,.3,..-0
0x0030:  2e31 3533 2c20 2d30 2e33 3036 2c20 2039  .153,.-0.306,..9
0x0040:  2e38 3037                                .807                                 

0x0000:  4500 0044 68fa 4000 4011 25c4 8083 d0bf  E..Dh.@.@.%.....
0x0010:  8083 da24 85b1 15b3 0030 2884 3132 3033  ...$.....0(.1203
0x0020:  3132 2e39 3336 3135 2c20 332c 2020 2030  12.93615,.3,...0
0x0030:  2e31 3533 2c20 2d30 2e31 3533 2c20 2039  .153,.-0.153,..9
0x0040:  2e38 3037                                .807

para

E..Dh.@.@.%.....
  ...$.....0..1203
  12.78606,.3,...0
.153,.-0.153,..9
.960

etc,

com este comando

sed -u -e 's_0x0000:  4500 0044 68f7 4000 4011 25c7 8083 d0bf  __g;s_0x0010:  8083 da24 85b1 15b3 0030 1e8b 3132 3033__g;s_0x0030:  2e31 3533 2c20 2d30 2e34 3630 2c20 2039__g;s_0x0020:  3132 2e37 3836 3036 2c20 332c 2020 2030__g;s_0x0040:  2e39 3630__g' <tcpdump_log_sample_capture2.txt >out2

e eu tenho

E..Dh.@.@.%.....
  ...$.....0..1203
  12.78606,.3,...0
0x0030:  2e31 3533 2c20 2d30 2e31 3533 2c20 2039  .153,.-0.153,..9
                                .960

0x0000:  4500 0044 68f8 4000 4011 25c6 8083 d0bf  E..Dh.@.@.%.....
0x0010:  8083 da24 85b1 15b3 0030 148f 3132 3033  ...$.....0..1203
0x0020:  3132 2e38 3336 3131 2c20 332c 2020 2d30  12.83611,.3,..-0
  .153,.-0.460,..9
                                .960

0x0000:  4500 0044 68f9 4000 4011 25c5 8083 d0bf  E..Dh.@.@.%.....
0x0010:  8083 da24 85b1 15b3 0030 1b80 3132 3033  ...$.....0..1203
0x0020:  3132 2e38 3836 3135 2c20 332c 2020 2d30  12.88615,.3,..-0
0x0030:  2e31 3533 2c20 2d30 2e33 3036 2c20 2039  .153,.-0.306,..9
0x0040:  2e38 3037                                .807                                 

0x0000:  4500 0044 68fa 4000 4011 25c4 8083 d0bf  E..Dh.@.@.%.....
0x0010:  8083 da24 85b1 15b3 0030 2884 3132 3033  ...$.....0(.1203
0x0020:  3132 2e39 3336 3135 2c20 332c 2020 2030  12.93615,.3,...0
0x0030:  2e31 3533 2c20 2d30 2e31 3533 2c20 2039  .153,.-0.153,..9
0x0040:  2e38 3037                                .807

Assim, nas primeiras 5 linhas, funcionou em todas as linhas, mas a quarta começou com 0x0030:

no segundo set funcionou para as duas últimas linhas, MAS não para as 3 primeiras, e para o 3º e 4º conjunto, funcionou para nenhum!

alguém pode dar uma olhada e me dizer o que está acontecendo? é suposto ser recursivo com a opção g!

(eu tenho o sed (GNU sed) 4.2.2)

    
por A robot from Mars 24.10.2014 / 00:36

4 respostas

1

Usando o GNU Sed com campos de largura fixa

Como o formato da sua saída parece estar formatado em campos de largura fixa, você pode obter os dados desejados simplesmente removendo os primeiros 50 caracteres de cada linha. Por exemplo:

sed -r 's/^.{50}//' /tmp/corpus
    
por 24.10.2014 / 02:22
0

Sempre que você vir um arquivo de texto com dados em colunas, pense em awk . Isso é feito trivialmente em awk :

$ awk '{print $NF}' file 
E..Dh.@.@.%.....
...$.....0..1203
12.78606,.3,...0
.153,.-0.153,..9
.960

E..Dh.@.@.%.....
...$.....0..1203
12.83611,.3,..-0
.153,.-0.460,..9
.960

E..Dh.@.@.%.....
...$.....0..1203
12.88615,.3,..-0
.153,.-0.306,..9
.807

E..Dh.@.@.%.....
...$.....0(.1203
12.93615,.3,...0
.153,.-0.153,..9
.807

A variável especial NF é o número de campos da linha atual. Portanto, $NF é o último campo da linha. Este script awk apenas passa por cada linha do arquivo e imprime o último campo.

Você pode fazer o mesmo em perl , se preferir:

perl -lane 'print $F[$#F]' file

Ou mesmo com o GNU grep:

grep -oP '.+\s\s*\K[^\s]+' file1

Ou, se você realmente quiser uma abordagem sed por algum motivo, use o GNU sed (ou qualquer outra versão que aceite expressões regulares estendidas) e:

 sed -r 's/.* +([^ ]+) *$//' file

O comando acima procura a cadeia mais longa que termina com um ou mais espaços ( .* + ), depois a cadeia mais longa de não espaços ( [^ ]+ ) e depois 0 ou mais espaços (  * ) e substitui a totalidade coisa com o padrão capturado (é isso que os parênteses fazem). Ainda assim, isso falhará se o arquivo tiver espaços em branco que não sejam de espaço, por exemplo. Awk é de longe a melhor ferramenta para isso.

    
por 24.10.2014 / 21:14
0

Não use sed -u - não faz o que você pensa. Qualquer buffer sed será para seu benefício, pois ajudará a aumentar a velocidade de processamento de sed em vez de outras. sed -u é realmente útil apenas em situações em que você deseja q uit input em um ponto muito específico e assegura que sed não consuma entrada além dele.

Por exemplo:

printf %s\n line1 line2 | {
    sed -u =\;1q
    sed =
}

... que imprime ...

1
line1
1
line2

... mas se o sinalizador -u não for usado, só imprimirá ...

1
line1

... porque o primeiro sed tentará preencher seu buffer com cada read() de chamada e consumirá todo o |pipe antes que o segundo sed tenha a chance de analisá-lo. Com a entrada de qualquer tamanho razoável, sed -u reduzirá significativamente a velocidade de processamento de sed , pois terá que fazer um read() por linha.

Isso, no entanto, não é problema seu.

Seu problema é que você está trabalhando demais. Faça:

sed 's/.* //' <infile >outfile

Isso removerá tudo em uma linha até e incluindo o último espaço que está ocorrendo. Dessa forma, você obterá apenas a saída desejada.

@CodeGnome está certo sobre isso não ser um caminho confiável. Embora funcione para os dados mostrados, outro caminho, mais robusto, pode ser:

sed 's/   */\n/2;s/.*\n//'

Substitui a segunda ocorrência de dois ou mais espaços consecutivos por um caractere \n ewline e, em seguida, remove tudo antes dele. Há apenas uma maneira de obter um caractere de% ewline \n no espaço padrão sed , e isso é colocando-o lá.

    
por 24.10.2014 / 07:16
-1

Você precisa fazer isso:

paste  -d ""  <( awk {'print $10'}  yourfile )  <( cut -b 51 yourfile ) <( cut -b 52 yourfile ) <( cut -b 53 yourfile )  <( cut -b 54 yourfile )

A saída é:

E..Dh.@.@.%.....E..D
...$.....0..1203...$
12.78606,.3,...012.7
.153,.-0.153,..9.153
.960

E..Dh.@.@.%.....E..D
...$.....0..1203...$
12.83611,.3,..-012.8
.153,.-0.460,..9.153
.960

E..Dh.@.@.%.....E..D
...$.....0..1203...$
12.88615,.3,..-012.8
.153,.-0.306,..9.153
.807

E..Dh.@.@.%.....E..D
...$.....0(.1203...$
12.93615,.3,...012.9
.153,.-0.153,..9.153
.807
    
por 24.10.2014 / 01:47