Linux 日志文件结构改变,异常(?)sed 行为

Linux 日志文件结构改变,异常(?)sed 行为

好的,所以我尝试得到这个

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

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

ETC,

用这个命令

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..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

因此,在前 5 行中,除了以 0x0030 开头的第四行之外,它在每一行都有效:

在第二组中,它对最后两行起作用,但对前三行不起作用,而对于第三组和第四组,它不起作用!

有人可以看看并告诉我发生了什么事吗?它应该是带有 g 选项的递归!

(我得到了 sed (GNU sed) 4.2.2)

答案1

将 GNU Sed 与固定宽度字段一起使用

由于输出的格式似乎被格式化为固定宽度字段,因此您只需从每行中删除前 50 个字符即可获得所需的数据。例如:

sed -r 's/^.{50}//' /tmp/corpus

答案2

每当您看到包含列中数据的文本文件时,请考虑awk.这是简单地完成的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

特殊变量NF是当前行的字段数。因此,$NF是该行的最后一个字段。该awk脚本仅遍历文件的每一行并打印最后一个字段。

perl如果您愿意,您也可以这样做:

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

或者甚至使用 GNU grep:

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

或者,如果您sed出于某种原因确实想要一种方法,请使用 GNU sed (或接受扩展正则表达式的任何其他版本)并且:

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

上面的命令查找以一个或多个空格 ( .* +) 结尾的最长字符串,然后查找最长的非空格字符串 ( [^ ]+),然后查找 0 个或多个空格 (  *) 并用捕获的模式替换整个字符串(这就是括号的作用) 。尽管如此,如果文件包含非空格空格,这仍然会失败。 awk 是迄今为止最好的工具。

答案3

不要使用sed -u——它不会做你想的那样。任何缓冲sed都会对您有利,因为它将有助于提高sed的处理速度,而不是其他。sed -u实际上仅在您想要q在非常特定的点上进行输入并确保sed不会消耗超出该点的输入的情况下才有用。

例如:

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

...打印...

1
line1
1
line2

...但是如果-u不使用该标志只会打印...

1
line1

...因为第一个sed将尝试用每次调用填充其缓冲区并在第二个有机会查看它之前read()消耗整个缓冲区。给定任何合理长度的输入,将显着降低的处理速度,因为它必须每行执行一次。|pipesedsed -usedread()

然而,这不是你的问题。

你的问题是你工作太努力了。做:

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

这将删除一行中直到并包括最后出现的空格的所有内容。这样你就会得到你想要的输出。

@CodeGnome 说得对,这不是一个可靠的方法。虽然它适用于您显示的数据,但另一种更可靠的方法可能是:

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

这会将第二次出现的两个或多个连续空格替换为\newline 字符,然后删除其之前的所有内容。\n在模式空间中获取 ewline 字符只有一种方法sed,那就是将其放在那里。

答案4

你必须这样做:

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

输出是:

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

相关内容