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
объяснение
Устанавливает ширину столбца, поле, которое мы хотим, начинается с позиции 101, так что это первое число, которое помещает все остальное в поле один, поле длиной 5 символов, так что это ширина второго поля, а затем 100 просто для того, чтобы перехватить все остальное.,
Проверяет, имеет ли поле 2
M
в нем, в то же время заменяя сказал М ни с чемЕсли это так, то поле 2 умножается на 1048576
1
в awk оценивается как true, и действием по умолчанию является печать строки.Труба в
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