0

我有一个 netflow 输出,其中某些行在字节后显示“M”:

2014-05-10 14:26:49.231    10.335 UDP     114.31.254.227:24874 ->    56.213.85.253:13617        9     1139     1
2014-05-10 14:26:59.494     0.222 UDP     114.31.254.193:17769 ->   165.199.57.179:40012        3      172     1
2014-05-10 14:26:56.015     3.348 TCP      96.196.161.39:80    ->   114.31.255.131:61066     5428    7.8 M     1
2014-05-10 14:26:59.705     0.246 UDP     165.199.57.144:40007 ->   114.31.254.193:17769        3      140     1

可以看出,有一个“7.8 M”的实例,我想将其显示为它的真实字节值,而不是兆字节。

我想用它们的字节值替换所有兆字节值(乘以 1,048,576)。

代码如下: match '[number string] M' 将 number 乘以 1048576 并替换

列是 9-10 在带有 M 的行上

也许使用 awk?:

cat whitespacetrim.out | grep ' M ' | cut -f 9,10 -d ' '| cut -f 1 -d ' ' | awk '{val=$1*1024*1024} END {print val}'|
4

3 回答 3

1

使用 GNU awk 为第三个参数保留原始间距和字段对齐到match()\s/\S

$ cat tst.awk
NF==11 {
    match($0,/((\S+\s+){7}\S+)((\s+\S+){2})(.*)/,a)
    $0 = a[1] sprintf("%*d",length()-length(a[1]a[5]),$9*1048576) a[5]
}
{ print }
$
$ awk -f tst.awk file
2014-05-10 14:26:49.231    10.335 UDP     114.31.254.227:24874 ->    56.213.85.253:13617        9     1139     1
2014-05-10 14:26:59.494     0.222 UDP     114.31.254.193:17769 ->   165.199.57.179:40012        3      172     1
2014-05-10 14:26:56.015     3.348 TCP      96.196.161.39:80    ->   114.31.255.131:61066     5428  8178892     1
2014-05-10 14:26:59.705     0.246 UDP     165.199.57.144:40007 ->   114.31.254.193:17769        3      140     1

match() 将输入记录分成 3 段 - 直到并包括第 8 个字段的部分((\S+\s+){7}\S+),然后是第 9 和第 10 个字段加上它们之前的空格((\s+\S+){2}),然后是它之后的所有内容(.*),在这种情况下只是最后的空格第 11 场。

然后,分配从前导部分和尾随部分重新创建 $0,其中空格+9th+空格+10th 字段被填充到它们总共占用的原始宽度的新计算值替换。

于 2015-04-14T13:16:34.223 回答
1

Gawk 中列宽可变的一种方式。

awk 'BEGIN{FIELDWIDTHS="101 5 100"}gsub("M","",$2){$2=$2*1048576}1' test | column -t

输出

2014-05-10  14:26:49.231  10.335  UDP  114.31.254.227:24874  ->  56.213.85.253:13617   9     1139         1
2014-05-10  14:26:59.494  0.222   UDP  114.31.254.193:17769  ->  165.199.57.179:40012  3     172          1
2014-05-10  14:26:56.015  3.348   TCP  96.196.161.39:80      ->  114.31.255.131:61066  5428  8.17889e+06  1
2014-05-10  14:26:59.705  0.246   UDP  165.199.57.144:40007  ->  114.31.254.193:17769  3     140          1

解释

  1. 设置列宽,我们想要的字段从位置 101 开始,这是第一个将所有其余部分放在字段一中的数字,该字段长 5 个字符,因此是第二个字段宽度,然后 100 只是为了捕捉其他所有内容.

  2. 检查字段 2 中是否有一个M,同时也将所述 M 替换为空

  3. 如果是,则字段 2 乘以 1048576

  4. 1在 awk 中计算为 true,默认操作是打印该行。

  5. 管进去column -t,所以它看起来像样:)

于 2015-04-14T13:16:06.023 回答
0

通过awk,

$ awk '/([0-9]+\.[0-9]+|[0-9]+)[[:blank:]]*M/{$9=$9*1048576;$10=""}{$1=$1}1' file
2014-05-10 14:26:49.231 10.335 UDP 114.31.254.227:24874 -> 56.213.85.253:13617 9 1139 1
2014-05-10 14:26:59.494 0.222 UDP 114.31.254.193:17769 -> 165.199.57.179:40012 3 172 1
2014-05-10 14:26:56.015 3.348 TCP 96.196.161.39:80 -> 114.31.255.131:61066 5428 8.17889e+06  1
2014-05-10 14:26:59.705 0.246 UDP 165.199.57.144:40007 -> 114.31.254.193:17769 3 140 1
于 2015-04-14T12:59:16.483 回答