Хотите знать, как объединить эти две команды bash в одну эффективную

У меня есть файл журнала, который содержит несколько строк, которые мне нужно захватить:

Jul  2 06:42:00 myhostname error proc[12345]: 01310001:3: event code xxxx Slow transactions attack detected - account id: (20), number of dropped slow transactions: (3)
Jul  2 06:51:00 myhostname error proc[12345]: 01310001:3: event code xxxx Slow transactions attack detected - account id: (20), number of dropped slow transactions: (2)

Идентификатор учетной записи (xx) дает мне имя объекта, который я могу собрать с помощью запроса mysql.

Следующая команда (которая, конечно, вообще не оптимизирована, но работает) дает мне количество совпадающих строк для идентификатора учетной записи:

grep "Slow transactions" logfile| awk '{print $18}' | awk -F '[^0-9]+' '{OFS=" ";for(i=1; i<=NF; i++) if ($i != "") print($i)}' | sort | uniq -c
 14 20

Вывод (14 20) означает, что идентификатор учетной записи 20 наблюдался 14 раз (14 строк в файле журнала).


Тогда у меня также есть количество отброшенных медленных транзакций: (2) часть. Это дает реальное количество зарегистрированных отброшенных транзакций. Другими словами, запись в журнале может означать одну или несколько отброшенных транзакций.

У меня есть небольшая команда для подсчета количества отброшенных транзакций:

grep "Slow transactions" logfile | awk '{print $24}' | sed 's/(//g' | sed 's/)//g' | awk '{s+=$1} END {print s}'
73

Это означает, что 73 транзакции были удалены.


Эти две работы, но когда дело доходит до слияния двух, я застрял. Я действительно не понимаю, как их комбинировать; Я почти уверен, что awk может это сделать (и, возможно, лучше, чем я), но я был бы признателен, если бы какой-либо эксперт из сообщества мог дать мне некоторые рекомендации.


обновление Поскольку приведенное выше было слишком просто для некоторых наших экспертов по awk в SO, я добавляю дополнительную функцию :)

Как упоминалось ранее, я могу преобразовать идентификатор учетной записи в имя, выдающее запрос mysql. Итак, теперь идея состоит в том, чтобы включить преобразование ID => name в команду awk.

Запрос mySQL выглядит следующим образом (XX — идентификатор учетной записи):

 mysql -Bs -u root -p$(perl -MF5::GenUtils -e "print get_mysql_password.qq{\n}") -e "SELECT name FROM myTABLE where account_id= 'XX'"

Я основал сообщение ниже, в котором речь идет о выводе команд в awk, но с синтаксическими ошибками...

Как передать переменные из awk в команду оболочки?


person Xxmusashi    schedule 02.07.2015    source источник


Ответы (1)


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

awk -F '[()]' '
    /Slow transactions/ {
        acct[$2]++
        dropped[$2] += $4
    }
    END {
        PROCINFO["sorted_in"] = "@ind_num_asc"     # https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html

        for (acctnum in acct)
            print acctnum, acct[acctnum], dropped[acctnum]
    }
' logfile

Учитывая ваш образец ввода, это выводит

20 2 5

Требуется GNU awk для метода sorted_in для сортировки обхода массива по индексу.

person glenn jackman    schedule 02.07.2015
comment
Почему вы их сортируете, я думаю, OP сделал это только для того, чтобы они могли использовать uniq? - person 123; 02.07.2015
comment
Спасибо за быстрый ответ. Я действительно получаю две команды в один выход. Но это не совсем то, что я ищу (возможно, мое описание недостаточно ясно): я хотел получить сумму X (отброшенных медленных транзакций: (X)) на идентификатор учетной записи (идентификатор учетной записи: ( ГГ)). - person Xxmusashi; 02.07.2015
comment
Спасибо, Гленн. Итак, если я хорошо понимаю, вы используете своего рода массив для хранения и вычисления значений, верно? Две строчки после поиска по шаблону меня немного смущают... Я их не очень понимаю ???? - person Xxmusashi; 02.07.2015
comment
мои разделители полей ( и ). Следовательно, 2-е поле — это номер счета, а 4-е поле — количество дропов. acct[$2]++ означает увеличение (на 1) значения в ассоциативном массиве acct по номеру счета index; а dropped[$2] += $4 означает приращение (на количество отбрасываний) значения в отброшенном ассоциативном массиве по номеру счета index - person glenn jackman; 03.07.2015
comment
Еще раз спасибо, Гленн, работает как шарм! Последнее, что я хотел сделать в качестве дополнения, — заменить идентификатор учетной записи ее именем. У меня есть команда mysql для сопоставления. Я отредактировал свой вопрос, чтобы у вас тоже была эта дополнительная задача. - person Xxmusashi; 03.07.2015