我需要一个脚本来处理文件并总结SLA探测器的中断。我的文件如下:
Jan 28 22:10:02 test-195869-st28
Jan 28 22:10:04 test-195869-st28
Jan 28 22:10:06 test-195869-st28
Jan 28 22:10:08 test-195869-st28
Jan 28 22:10:10 test-195869-st28
Jan 28 22:10:12 test-195869-st28
Jan 28 22:10:14 test-195869-st28
Jan 28 22:15:16 test-195869-st28
Jan 28 23:12:34 test-195869-st28
Jan 28 23:12:36 test-195869-st28
Jan 28 23:12:38 test-195869-st28
Jan 28 23:12:40 test-195869-st28
Jan 28 23:12:42 test-195869-st28
Jan 28 23:12:44 test-195869-st28
Jan 28 23:12:46 test-195869-st28
Jan 28 23:12:48 test-195869-st28
Jan 28 23:12:50 test-195869-st28
Jan 28 23:12:52 test-195869-st28
Jan 29 13:12:18 test-195869-st28
Jan 29 13:12:20 test-195869-st28
Jan 29 13:12:22 test-195869-st28
Jan 29 13:12:24 test-195869-st28
Jan 29 13:12:26 test-195869-st28
Jan 29 13:12:28 test-195869-st28
Jan 29 13:12:30 test-195869-st28
Jan 29 13:12:32 test-195869-st28
Jan 29 13:12:34 test-195869-st28
Jan 29 13:12:36 test-195869-st28
所需的输出如下
Jan 28 22:10:02 test-195869-st28
...
Jan 28 22:10:14 test-195869-st28
Jan 28 22:15:16 test-195869-st28
Jan 28 23:12:34 test-195869-st28
...
Jan 29 13:12:36 test-195869-st28
应该总结所有中断(单个30秒间隔内的所有中断都是单次中断)。但是,单个第二次中断应作为单个条目保留在日志中。
直到现在我正试图用awk从文件中读取:
awk 'BEGIN{prevDt=0;}
{
getDate="date -d \""$1" "$2" "$3"\" \"+%s\""
print "Get date:" (getDate);
while ( ( getDate | getline date ) > 0 ) {
Diff=date-prevDt
prevDt=date;
print "Difference: "Diff" "$1" "$2" "$3" "$12;
}
close(getDate);
} END { print $date }'
我正在考虑将这种差异用于以后的比较。
谢谢
答案 0 :(得分:2)
当时间戳之间有30秒的时间间隔重叠时,不清楚你想要采用什么逻辑,所以这里是如何用GNU awk创建一个时间戳数组并按你喜欢的方式使用它:
$ cat tst.awk
NR==FNR {
year = strftime("%Y")
month = (match("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3
day = $2
time = gensub(/:/," ","g",$3)
secs = mktime(year" "month" "day" "time)
print year, month, day, time, "=>", secs
outages[NR] = secs FS $0
next
}
{
# loop through "outages" starting at current
# line number to find those with first value
# (secs) within 30 of the current value.
}
$ awk -f tst.awk file
2016 1 28 22 10 02 => 1454040602
2016 1 28 22 10 04 => 1454040604
2016 1 28 22 10 06 => 1454040606
2016 1 28 22 10 08 => 1454040608
2016 1 28 22 10 10 => 1454040610
2016 1 28 22 10 12 => 1454040612
2016 1 28 22 10 14 => 1454040614
2016 1 28 22 15 16 => 1454040916
2016 1 28 23 12 34 => 1454044354
2016 1 28 23 12 36 => 1454044356
2016 1 28 23 12 38 => 1454044358
2016 1 28 23 12 40 => 1454044360
2016 1 28 23 12 42 => 1454044362
2016 1 28 23 12 44 => 1454044364
2016 1 28 23 12 46 => 1454044366
2016 1 28 23 12 48 => 1454044368
2016 1 28 23 12 50 => 1454044370
2016 1 28 23 12 52 => 1454044372
2016 1 29 13 12 18 => 1454094738
2016 1 29 13 12 20 => 1454094740
2016 1 29 13 12 22 => 1454094742
2016 1 29 13 12 24 => 1454094744
2016 1 29 13 12 26 => 1454094746
2016 1 29 13 12 28 => 1454094748
2016 1 29 13 12 30 => 1454094750
2016 1 29 13 12 32 => 1454094752
2016 1 29 13 12 34 => 1454094754
2016 1 29 13 12 36 => 1454094756
当您掌握了最终逻辑时,请注释当前的print
行。
答案 1 :(得分:1)
这将做你想要的:
#!/bin/bash
LogFile="mylog.log"
function Get-LineDate(){
local Line="$1"
if [[ "$Line" != "" ]]; then
local LineDate=$(grep -oP ".*(?= test)" <<< "$Line")
local LineDate=$(date -d "$LineDate" +"%s")
echo "$LineDate"
fi
}
function Get-DateDiff(){
local DateOne="$1"
local DateTwo="$2"
if [[ "$DateOne" != "" ]] && [[ "$DateTwo" != "" ]]; then
local DateDiff=$(( $DateOne -$DateTwo))
echo "$DateDiff"
fi
}
count=0
while read -r line; do
if [[ "$count" -eq 0 ]]; then
prevline="$line"
prevdate=$(Get-LineDate "$line")
echo "$line"
count="1"
else
linedate=$(Get-LineDate "$line")
datediff=$(Get-DateDiff "$linedate" "$prevdate")
if [[ "$datediff" -ge 30 ]]; then
echo "$prevline -> $line - Interval: $datediff (seconds)"
fi
prevline="$line"
prevdate="$linedate"
fi
done < $LogFile
完整摘要输出:
Jan 28 22:10:02 test-195869-st28
Jan 28 22:10:14 test-195869-st28 -> Jan 28 22:15:16 test-195869-st28 - Interval: 302 (seconds)
Jan 28 22:15:16 test-195869-st28 -> Jan 28 23:12:34 test-195869-st28 - Interval: 3438 (seconds)
Jan 28 23:12:52 test-195869-st28 -> Jan 29 13:12:18 test-195869-st28 - Interval: 50366 (seconds)
如果您希望确切输出,则需要将while循环/逻辑更改为:
while read -r line; do
if [[ "$count" -eq 0 ]]; then
prevline="$line"
prevdate=$(Get-LineDate "$line")
LineArr+=("$line")
echo "$line"
else
linedate=$(Get-LineDate "$line")
datediff=$(Get-DateDiff "$linedate" "$prevdate")
if [[ "$datediff" -ge 30 ]]; then
for item in "${LineArr[@]}"; do
if [[ "$item" == "$prevline" ]]; then
bit=1
break
fi
done
if [[ "$bit" != "1" ]]; then
echo "$prevline"
LineArr+=("$prevline")
else
bit=""
fi
for item in "${LineArr[@]}"; do
if [[ "$item" == "$line" ]]; then
bit=1
break
fi
done
if [[ "$bit" != "1" ]]; then
echo "$line"
LineArr+=("$line")
else
bit=""
fi
fi
prevline="$line"
prevdate="$linedate"
fi
count=$(( $count +1 ))
done < $LogFile
输出:
Jan 28 22:10:02 test-195869-st28
Jan 28 22:10:14 test-195869-st28
Jan 28 22:15:16 test-195869-st28
Jan 28 23:12:34 test-195869-st28
Jan 28 23:12:52 test-195869-st28
Jan 29 13:12:18 test-195869-st28
答案 2 :(得分:1)
以下是最终代码:
#!/bin/bash
LogFile="test"
function Get-LineDate(){
local Line="$1"
if [[ "$Line" != "" ]]; then
local LineDate=$(grep -oP ".*(?= MGIM0-test)" <<< "$Line")
local LineDate=$(date -d "$LineDate" +"%s")
echo "$LineDate"
fi
}
function Get-DateDiff(){
local DateOne="$1"
local DateTwo="$2"
if [[ "$DateOne" != "" ]] && [[ "$DateTwo" != "" ]]; then
local DateDiff=$(( $DateOne -$DateTwo))
echo "$DateDiff"
fi
}
count=0
interval=0
prev_int=0
while read -r line; do
if [[ "$count" -eq 0 ]]; then
prevline="$line"
prevdate=$(Get-LineDate "$line")
# echo "$line"
count="1"
start_int="$line"
else
linedate=$(Get-LineDate "$line")
datediff=$(Get-DateDiff "$linedate" "$prevdate")
prev_int=$interval
interval=$(( $datediff + $interval ))
# echo "Interval: $interval Previnterval: $prev_int"
if [[ "$interval" -gt "$(( $prev_int+30 ))" ]] && [[ "$prev_int" -eq "0" ]]; then
echo "$start_int - Single seconds outage"
start_int="$line"
fi
if [[ "$interval" -gt "$(( $prev_int+30 ))" ]]; then
echo -e "$start_int \n ... \n$prevline"
# echo "$start_int -> $prevline - Interval: $prev_int (seconds)
start_int="$line"
interval=0
prev_int=0
fi
# if [[ "$datediff" -ge 30 ]]; then
# echo "$prevline -> $line - Interval: $datediff (seconds)"
# fi
prevline="$line"
prevdate="$linedate"
fi
done < $LogFile
if [[ "$start_int" == "$prevline" ]]; then
echo "$start_int - Single seconds outage"
else
echo "$start_int -> $prevline"
fi
全部谢谢!