2016-04-21 23 views
0

我需要拆分2015年10月至2016年2月的大型syslog文件,並按月分隔。由於後臺日誌保留,這些日誌的格式是類似於:需要一個腳本根據日誌的順序來確定一年的大文件

Oct 21 08:00:00 - Log info 
Nov 16 08:00:00 - Log Info 
Dec 25 08:00:00 - Log Info 
Jan 11 08:00:00 - Log Info 
Feb 16 08:00:00 - Log Info 

這個大文件是在由天拆分大量的日誌文件的初始zgrep搜索的結果。例如,跨越多個服務(例如Windows /防火牆/物理訪問日誌)的網絡上的用戶活動。

對於前一個請求,我用了以下內容:

gawk 'BEGIN{ 
m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",mth,"|")  
} 
{ 
for(i=1;i<=m;i++){ if (mth[i]==$1){ month = i } } 
tt="2015 "month" "$2" 00 00 00" 
date= strftime("%Y%m",mktime(tt)) 
print $0 > FILENAME"."date".txt" 
} 
' logfile 

輸出文件的例子(注意:有時我添加「%d」,以獲得一天,但不是這個時間:

Test.201503.txt 
Test.201504.txt 
Test.201505.txt 
Test.201506.txt 

這腳本會手動添加2015到輸出日誌文件的名稱,我試圖做的和未能做到的是一個腳本,它在1-12的每個月創建變量,然後將2015設置爲變量(a)和2016作爲變量( b)。然後腳本可以按照10,11,12,1,2的順序進行比較我會按順序進行,一旦它達到1 < 12(上個月),它會知道使用2016年而不是2015年。奇怪的要求我知道,但任何想法至少會幫助我達到正確的心態。

回答

1

您可以使用date解析日期和時間。例如。

#!/bin/bash 
while IFS=- read -r time info; do 
    mon=$(date --date "$time" +%m | sed 's/^0//') 
    if ((mon < 10)); then 
     year=2016 
    else 
     year=2015 
    fi 
    echo $time - $info > Test.$year$(printf "02d%" $mon).txt 
done 
1

這是一個基於您的腳本和您的問題觀察gawk解決方案。這個想法是在月份突然變小的時候檢測新的一年,例如從12變爲1.(當然,如果日誌在2015年1月之後直接跟隨在2016年1月之後,則不會工作。)

腳本.awk

BEGIN { START_YEAR= 2015 
     # configure months and a mapping month -> nr, e.g. "Feb" |-> "02" 
     split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",monthNames,"|") 
     for(nr in monthNames) { month2Nr[ monthNames[ nr ] ] = sprintf("%02d", nr) } 
     yearCounter=0 
     } 

     { 
     currMonth = month2Nr[ $1 ] 
     # detect a jump to the next year by a reset in the month number 
     if(prevMonth > currMonth) { yearCounter++ } 
     newFilename = sprintf("%s.%d%s.txt", FILENAME, (START_YEAR + yearCounter), currMonth) 
     prevMonth = currMonth 

     print $0 > newFilename 
     } 

使用方法如下:awk -f script.awk logfile

相關問題