Bash манипуляции столбцами Netflow

У меня есть вывод 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 МБ", который я хотел бы показать как истинное значение байта, а не мегабайт.

Я хочу заменить все мегабайтные долоты их байтовыми долями (умножая на 1048576).

Код в строке: соответствует "[числовая строка] M" умножить число на 1048576 и заменить

Столбец 9-10 в строках с М

Возможно, используя awk?

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

3 ответа

Способ с переменной шириной столбца в 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 в нем, в то же время заменяя сказал М ни с чем

  3. Если это так, то поле 2 умножается на 1048576

  4. 1 в awk оценивается как true, и действием по умолчанию является печать строки.

  5. Труба в column -t так выглядит презентабельно:)

Сохранение исходного интервала и выравнивания поля с использованием GNU awk для 3-го аргумента 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 из передней и задней частей, при этом пробелы +9-е + пробелы +10-е поля заменяются новым вычисленным значением, дополненным до первоначальной ширины, которую они заняли в общей сложности.

Через 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
Другие вопросы по тегам