Вот Bash решение для версии 4 и выше, с помощью ассоциативного массива:
#!/bin/bash
# Assoc array to hold data.
declare -A data
# Log file (the input file).
logfile=$1
# Output file.
output_file=$2
# Print column names for required values.
printf '%-20s %-10s %-10s %-10s\n' time latency99 requests errors > "$output_file"
# Iterate over each line in $logfile
while read -ra arr; do
# Insert keys and values into 'data' array.
for i in "${arr[@]}"; do
data["${i%=*}"]="${i#*=}"
done
# Convert time to GMT+2
gmt2_time=$(TZ=GMT+2 date -d "@${data[time]}" '+%T')
# Print results to stdout.
printf '%-20s %-10s %-10s %-10s\n' "$gmt2_time" "${data[latency99]%ms}" "${data[requests]}" "${data[errors]}" >> "$output_file"
done < "$logfile"
Как вы можете видеть, сценарий принимает два аргумента. Первый - это имя файла журнала, а второй - это выходной файл, в который будут вставлены анализируемые данные по строкам для каждой строки в файле журнала.
Обратите внимание, что я использовал GMT+2
как значение переменной TZ
. Используйте точную область как значение вместо этого. Например, TZ="Europe/Berlin"
. Возможно, вы захотите использовать инструмент tzselect
, чтобы узнать правильное строковое значение вашей области.
Для того чтобы проверить это, я создал следующий лог-файл, содержащий 3 разные строки ввода:
time=1260196536.242325 latency=3:6:7:9:16:(8)ms latency95=11ms latency99=10ms requests=100 option1=0 option2=0 errors=1 throughput=480rps ql=1 rr=0.00% cr=0.00% accRequests=101468 accOption1=0 accOption2=0 accLatency=2:6:7:8:3998:(31)ms accLatency95=11ms accLatency99=649ms accOpenQueuing=1664 accErrors=278
time=1460246536.244325 latency=3:6:7:9:16:(8)ms latency95=11ms latency99=20ms requests=200 option1=0 option2=0 errors=2 throughput=480rps ql=1 rr=0.00% cr=0.00% accRequests=101468 accOption1=0 accOption2=0 accLatency=2:6:7:8:3998:(31)ms accLatency95=11ms accLatency99=649ms accOpenQueuing=1664 accErrors=278
time=1260236536.147325 latency=3:6:7:9:16:(8)ms latency95=11ms latency99=30ms requests=300 option1=0 option2=0 errors=3 throughput=480rps ql=1 rr=0.00% cr=0.00% accRequests=101468 accOption1=0 accOption2=0 accLatency=2:6:7:8:3998:(31)ms accLatency95=11ms accLatency99=649ms accOpenQueuing=1664 accErrors=278
Давайте запустим тест (имя скрипта соф):
$ ./sof logfile parsed_logfile
$ cat parsed_logfile
time latency99 requests errors
12:35:36 10 100 1
22:02:16 20 200 2
23:42:16 30 300 3
EDIT:
Согласно запросу OP, как видно из комментариев, и, как обсуждалось далее в чате, я редактировал сценарий включает в себя следующие функции:
- Удалить
ms
суффикс от значения latency99
«s.
- Чтение ввода из файла журнала, строка за строкой, анализ и вывод результатов в выбранный файл .
- Включить имена столбцов только в первой строке вывода.
- Преобразование значения времени в GMT + 2.
По какой-то причине, я получаю это: (Bash версии 4.2.25) './test.sh колонка: линия слишком долго времени latency99 запросы errors' – user3580316
Я вижу. Это предел длины входной строки в байтах, определяемой 'column'. Я отредактировал свой ответ, чтобы использовать только 'printf'. –
Как удалить «мс» после 13? Мне нужно определить файл журнала, который он читает за строкой, а затем записывает вывод в другой файл? – user3580316