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
Ионары могут быть вложенными, чтобы вы могли использовать эту возможность.
Обратите внимание, что у меня нет четкого представления о том, что на самом деле представляет собой ваш файл журнала, поэтому, возможно, элементы вашего ассоциативного массива должны сохранять некоторые другие значения, но общая идея остается в силе: это задача для ассоциативного массива.