2016-02-11 114 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 

謝謝大家!