2017-10-21 13 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スクリプトは、この目標を達成したが、耐え難いほど遅いペースで形式のログファイルを考えます。 500mbの入力ログは、8コア32GBマシンで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 

どのように私はこのスクリプトを最適化できますか?正規表現がボトルネック(私の最初の最適化)であるようには見えません。

ログファイル内の行のほとんどは1行であるため、最初の11文字を比較すると計算コストが高くなるとは思われません。

ありがとうございました。

+2

ただPythonを使用してください。それは、あなたが1行を読むたびにプロセスを産み出すよりずっと良いでしょう。または、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="; "}:それは数字で始まる場合、レコードにORS=""と先頭に追加RSまたは\nを設定します。行は、代わりにデフォルト\n

/^[0-9]/{$0=(FNR==1)?$0:RS $0; ORS=""};として非桁その後、設定出力レコードセパレータで始まる場合(最初の行を除いて、すなわち、最初に改行が必要でないところのFNR==1を除いて)

+1

ありがとう!これは素晴らしいです。私は開始日を解析する際に少し積極的になるように正規表現を修正しなければならなかったが、その作業は素晴らしかった。説明ありがとう。 – jammmie999

1

あなたは、あなたのニーズに '[0-9] [0-9] *' をあなたは正規表現を調整することができ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 

を使用することができます。それは複数のプロセスを起動しませんようawkの

を使用して