TCL: Как сгруппировать сообщения журнала вместе на основе отметок даты

Я довольно новичок в TCL и нуждаюсь в некоторой помощи, объединяющей сообщения журнала вместе на основе отметок даты от маршрутизатора Cisco.

ОБНОВЛЕНО: изменение в журнале образцов. обнаружили, что есть дополнительный пробел, когда DD является одной цифрой. например, "1"

Samplelog: показать логирование

THREADID: Feb  1 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  1 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  1 HH:MM:SS.SSS  : %TYPE-OF-VAIRBLE: OFFLINE
THREADID: Feb  1 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  3 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Feb  3 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Feb  4 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  4 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 15 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Mar 15 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 15 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 16 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Mar 16 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 16 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN

Желаемый вывод

Feb 01 || 3 down
Feb 04 || 2 down
Mar 15 || 2 down
Mar 16 || 2 down

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

set y [read -nonewline [set f [open "tmp.txt" r]]];

array set counts [list];
foreach message [split $y "\n"] {
    # This gets the status, ie: DOWN/UP/OFFLINE.
    set status [lindex [split $message] end]; # will assign last field
    set mon [lindex [split $message] 1]; # number represents the filed number
    set day [lindex [split $message] 2];
    if {$day ==""} {
        set day [lindex [split $message] 3];
     } else {
        set day [lindex [split $message] 2]
    }
        # +number represents the counter
    if {[info exists counts($mon,$day,$status)]} {
            set counts($mon,$day,$status) [expr {$counts($mon,$day,$status)+1}] 
    } else {
            set counts($mon,$day,$status) 1
    }   
}

# sort based for down type events

puts "\n\n MMM DD || Cnt Status"
puts " ====================="

foreach count [lsort -increasing -unique [array names counts]] {

    foreach {mon day status} [split $count ","] { break; }
    if {$status =="down"} {
    puts " $mon $day || [set counts($count)] \t $status"
    }
}

if {[info exists f]} { close $f }

2 ответа

Решение

Попробуйте это - вам нужно изменить "file.txt" на ваш файл журнала.

set y [read -nonewline [set f [open "file.txt" r]]];

array set counts [list];
foreach message [split $y "\n"] {
        # This gets the status, ie: DOWN/UP/OFFLINE.
        set status [lindex [split $message] end];
        set id [lindex [split $message] 3];
        if {[info exists counts($id,$status)]} {
                set counts($id,$status) [expr {$counts($id,$status)+1}]
        } else {
                set counts($id,$status) 1
        }
}

foreach count [lsort -increasing -unique [array names counts]] {
        foreach {name status} [split $count ","] { break; }
        puts "MMM $name || [set counts($count)] $status"
}

if {[info exists f]} { close $f }

Вывод для этого (для примера журнала, который вы дали) дает:

MMM 01 || 3 DOWN
MMM 01 || 1 OFFLINE
MMM 03 || 2 UP
MMM 04 || 2 DOWN

Просто используйте ассоциативный массив - array (так!) или dict (появился в Tcl 8.5).

Перед сканированием ваш массив пуст, и когда вы сканируете файл журнала и анализируете строки текста из него (в зависимости от фактического формата файла это можно сделать с помощью split или же regexp или же string range и т. д.), вы проверяете, существует ли в массиве запись, соответствующая вашим критериям группировки. Если это не так, вы вставляете некоторую структуру данных в ваш массив, заполненную некоторыми начальными значениями. Если соответствующая запись существует, вы обновляете связанную с ней структуру данных новыми данными.

Что касается фактических структур данных... Для array s Я бы использовал двухэлементный list s - с элементами, содержащими количество событий "вверх" и "вниз" соответственно. dict Ионары могут быть вложенными, чтобы вы могли использовать эту возможность.

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

Другие вопросы по тегам