2017-10-21 163 views
1

我寫了一個負責'摺疊'日誌文件的bash腳本。鑑於格式的日誌文件:bash腳本的性能問題

21 Oct 2017 12:38:03 [DEBUG] Single line message 
21 Oct 2017 12:38:05 [DEBUG] Multi line 
message 
that may continue 
several lines 
21 Oct 2017 12:38:07 [DEBUG] Single line message 

崩潰日誌文件,以一個單一的內襯文件用分隔符:

21 Oct 2017 12:38:03 [DEBUG] Single line message 
21 Oct 2017 12:38:05 [DEBUG] Multi line; message; that may continue; several lines 
21 Oct 2017 12:38:07 [DEBUG] Single line message 

以下bash腳本實現了這一目標,但在速度奇慢的速度。在8核32 GB的機器上,500MB輸入日誌可能需要30分鐘。

while read -r line; do 

    if [ -z "$line" ]; then 
    BUFFER+=$LINE_SEPERATOR 
    continue 
    done 

    POSSIBLE_DATE='cut -c1-11 <<< $line' 
    if [ "$PREV_DATE" == "$POSSIBLE_DATE" ]; then # Usually date won't change, big comparison saving. 
    if [ -n "$BUFFER" ]; then 
     echo $BUFFER 
     BUFFER="" 
    fi 

    BUFFER+="$line" 
    elif [[ "$POSSIBLE_DATE" =~ ^[0-3][0-9]\ [A-Za-z]{3}\ 2[0-9]{3} ]]; then # Valid date. 
    PREV_DATE="$POSSIBLE_DATE" 
    if [ -n "$BUFFER" ]; then 
     echo $BUFFER 
     BUFFER="" 
    fi 

    BUFFER+="$line" 
    else 
    BUFFER+="$line" 
    fi 
done 

任何想法如何優化這個腳本?它看起來好像是正則表達式是瓶頸(我的第一個優化),因爲現在這個條件很少被觸及。

日誌文件中的大部分行都是單行的,所以它只是前面11個字符的直線比較,看起來好像不像計算上那麼昂貴?

謝謝。

+2

只需使用Python。每當你閱讀一行時,它會比產卵過程好得多。或者使用AWK。 –

+0

'POSSIBLE_DATE ='cut -c1-11 <<< $ line''除非存在複製粘貼問題,您的條件未測試您想要的內容... – Mat

回答

2

這將是更加更快,因爲它不會產生多個進程。

$ awk '/^[^0-9]/{ORS="; "} /^[0-9]/{$0=(FNR==1)?$0:RS $0; ORS=""} END{printf RS}1' file 
21 Oct 2017 12:38:03 [DEBUG] Single line message 
21 Oct 2017 12:38:05 [DEBUG] Multi line message; that may continue ; several lines; 
21 Oct 2017 12:38:07 [DEBUG] Single line message 

/^[^0-9]/{ORS="; "}:如果符合非數字然後設置輸出記錄分隔開始爲;而不是默認\n

/^[0-9]/{$0=(FNR==1)?$0:RS $0; ORS=""}:如果它以數字開頭,然後設置ORS=""和前置RS\n的記錄(除了第一行,例如FNR==1,我們不想在開始時換行)

+1

謝謝!這很好。我不得不修改正則表達式在分析開始日期時更加積極,但它的工作非常出色。感謝您的解釋。 – jammmie999

1

您可以用sed

sed ':B;/^[0-9][0-9]* /N;/\n[0-9][0-9]* /!{s/\n/; /;bB};h;s/\n.*//p;x;s/.*\n//;tB' infile 

可以調整正則表達式 '[0-9] [0-9] *' 您的需要。使用AWK