2016-02-11 113 views
-1

我需要一个脚本来与文件工作,并总结了从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

在最小编辑你的问题来格式化使用'{}'编辑按钮,您的样品的输入和输出,并提供到目前为止你已经尝试了什么。摆脱所有'...'和其他任何可能导致您的示例输入/输出无法测试的内容。 –

+0

所以你需要在输出中包含'...'的行,对吧?你有没有或可以获得GNU awk?为什么'Jan 28 23:12:34 test-195869-st28 ... Jan 29 13:12:36 test-195869-st28'在输出中分组,好像它们是30秒范围一样?如果输入具有重叠的时间戳,那么输出是什么'10:20:00 ... 10:20:20 ... 10:20:40'? –

回答

2

目前还不清楚你想要什么逻辑来使用时,有时间戳withing 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

这会做你想要什么:

#!/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 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 
+0

请参阅http://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice –

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 

谢谢大家!