СОЗДАТЬ ЛОГИКУ - что может быть лучше, чем использование AWK?

Добавить репозиторий Intel:

sudo sh -c 'echo "deb https://download.01.org/gfx/ubuntu/12.04/main Ubuntu 12.04" >> /etc/apt/sources.list.d/intel-graphics.list'

Затем загрузите и установите GPG с помощью 2 команд:

wget https://download.01.org/gfx/RPM-GPG-KEY-ilg -O - | sudo apt-key add -

и

wget https://download.01.org/gfx/RPM-GPG-KEY-ilg-2 -O - | sudo apt-key add -

установить драйвер графики Intel:

sudo apt-get update; sudo apt-get install intel-linux-graphics-installer
2
04.04.2019, 12:34
4 ответа

вам нужно запомнить номер запроса.

Я бы использовал (это может быть однострочный)

awk -F= '$1 == "Req_id" {r=$2 ; } 
   $1 == "Time_taken" { printf "Request id %s %s %s\n",r,$1,$2 ; }' file |
sort -r -n -k5 |
head -3

которые дают

Request id 3456 Time_taken 200 sec
Request id 3001 Time_taken 15 sec
Request id 1234 Time_taken 10 sec

где

  • -F=используйте =в качестве разделителя
  • $1 == "Req_id" {r=$2 ; }получить идентификатор последнего запроса
  • $1 == "Time_taken"если строка "занято"
  • { printf "Request id %s %s %s\n",r,$1,$2 ; }идентификатор запроса на печать и секунды
  • | sortтруба для сортировки
  • -rобратный порядок
  • -nчисловая сортировка (например. 200 больше 15)
  • -k5на 5-м поле
  • | head -3получить первые 3 строки
1
27.01.2020, 21:53

Я бы предпочел Python awk во всем, кроме одного -вкладыша. Использование скрипта Python позволит вам легче обрабатывать плохо отформатированные входные данные, а также выполнять регистрацию и обработку ошибок -.

Вот базовый скрипт Python, который выдаст желаемый результат для вашего примера ввода и имеет структуру, наводящую на мысль о том, как вы могли бы построить его дальше, если это необходимо:

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""parse_log.py"""

import sys
from collections import OrderedDict

logfilepath = sys.argv[1]

# Define a function to parse a single block/entry in the log file
def parse_block(block):
    parsed_block = dict()
    lines = block.split("\n")
    for line in lines:
        if line.startswith("Company="):
            parsed_block["Company"] = line[8:]
        elif line.startswith("Req_id="):
            parsed_block["Required_ID"] = line[7:]
        elif line.startswith("Time_taken="):
            parsed_block["Time_Taken"] = line[11:]
        elif line.startswith("Status="):
            parsed_block["Status"] = line[7:]
        else:
            pass
    return parsed_block

# Initialize a list to store the processed entries
parsed_blocks = list()

# Populate the list
with open(logfilepath, "r") as logfile:
    blocks = logfile.read().split("\n\n")
    for block in blocks:
        parsed_block = parse_block(block)
        parsed_blocks.append(parsed_block)

# Print the results
print("Below Request Id took more then expected")
for parsed_block in parsed_blocks:
    print("Request id {}, Time Taken: {}".format(parsed_block["Required_ID"], parsed_block["Time_Taken"]))

Можно запустить так:

python parse_log.py data.log

В вашем примере ввода он производит следующий вывод (в соответствии с запросом):

Below Request Id took more then expected
Request id 1234, Time Taken: 10 sec
Request id 3456, Time Taken: 200 sec
Request id 3001, Time Taken: 15 sec
1
27.01.2020, 21:53

Использование толькоawk:

function list_insert (value, id, tmp) {
    for (i = 1; i <= list_length; ++i)
        if (value > value_list[i]) {
            tmp = value_list[i]
            value_list[i] = value
            value = tmp

            tmp = id_list[i]
            id_list[i] = id
            id = tmp
        }
}

BEGIN {
    FS = "[= ]"
    list_length = 3
}

$1 == "Req_id"     { id = $2 }
$1 == "Time_taken" { list_insert($2, id) }

END {
    printf("Below Request Id took more then expected\n")
    for (i = 1; i <= list_length; ++i)
        printf("Request id %d, time taken %d sec\n", id_list[i], value_list[i])
}

Эта программа поддерживает два массива, value_listи id_list, оба имеют длину list_length. Массив value_listотсортирован и содержит значения времени, а массив id_listсодержит идентификаторы запросов, соответствующие значениям в первом списке.

Функция list_insertвставляет новое значение и идентификатор в два массива таким образом, чтобы порядок массива value_listсохранялся (она находит правильное место для вставки, а затем перемешивает оставшиеся элементы в направлении конец ).

Остальная часть программы считывает данные как разделенные новой строкой -записи полей, разделенных =или пробелами. При обнаружении идентификатора запроса он сохраняется в id, а при обнаружении записи «затраченного времени» этот идентификатор и значение затраченного времени вставляются в массивы.

В конце два массива используются для создания вывода.

Проверка:

$ awk -f script.awk file
Below Request Id took more then expected
Request id 3456, time taken 200 sec
Request id 3001, time taken 15 sec
Request id 1234, time taken 10 sec
2
27.01.2020, 21:53

Мы можем сделать это, используя режим абзаца из Perl, в котором мы читаем фрагменты файлов размером с абзац в виде записей и создаем хеш-ключи с идентификаторами и значениями по времени. В конце файла мы сортируем числа в обратном порядке по затраченному времени, а затем печатаем желаемое сообщение.

$ perl -ln -00 -e '
    %h = (%h, /^Req_id=(\d+)\n.*^Time_taken=(\d+)/ms)}{
    print "The below IDs took more than expected:" if scalar keys %h;
    print join " ", "Req ID:", "$_,", "Time taken", $h{$_}, "sec"
       for (sort { $h{$b} <=> $h{$a}  } keys %h)[0..2];
' input.file

Выход:

The below IDs took more than expected:
Req ID: 3456, Time taken 200 sec
Req ID: 3001, Time taken 15 sec
Req ID: 1234, Time taken 10 sec
2
27.01.2020, 21:53

Теги

Похожие вопросы