2016-04-30 14 views
1

私のプロジェクトは、ログファイルから特定のデータを抽出することです。bash、regex、後処理行と列のデータ

データには列と行があります。いくつかはテキスト文字列であり、いくつかは数値です。

awk '{if($1 == text1Exp || textExp2 || textExp3) {print $1, $2}}' file.log 

まあ、そううまく動作しなかった:私はこのように見えたもの(年齢前)に動作するために使用さawkコマンドを試してみましたIに興味を持っていた情報の行のみを抽出するために

。私は私が欲しかっただけのデータで200以上のファイルを処理し

for i in `ls`; do awk '/Counter/ || /IfInErrors/ || /IfOutErrors/ {print $0}' $i > $i.csv; done 

:私はよく働い短いスクリプトを作っ

awk '/Counter/ || /IfInErrors/ || /IfOutErrors/ {print $0}' 

:検索は私によく働い次の構文を与えました。今では、タブとスペースがすべて1つの長さに設定されたcsvファイルとしてインポートできるデータが必要でした。私は繰り返し、次を使用して、これを達成:続く

sed -i 's/ */ /g' *.csv # all tab white space and white space set 

sed -i "s/ /,/g" *.csv  # substitute spaces with a comma. 

データのフォーマットをクリーンアップし、いくつかの他の置換がありました。 (。; I verは0.2Aでそれを修正します、私は主要なカンマについて知っているが、怠け者だ)

,Counter Name,port 1/1/x33,port 1/1/x34,port 1/1/x35,port 1/1/x36 
,IfInErrors:,0,0,0,0 
,IfOutErrors:,0,0,0,0 
,Counter Name,port 1/1/x37,port 1/1/x38,port 1/1/x39,port 1/1/x40 
,IfInErrors:,**95**,0,0,0 
,IfOutErrors:,0,0,0,0 

:今、私はこのようなクリーン探してデータを持っています。

  1. は& & IfOutErrors
  2. IfInErrorsためNON ZERO値の数をカウントして行を無視IfInErrorsためZERO値の数をカウントし& & IfOutErrors
  3. は、私は、次の達成したいですカウンタ...

  4. IfInErrorsのNON ZERO値の合計を報告してください。& & IfO utErrorsと
  5. レポートをファイルにゼロ値の合計をキャプチャし、要件4.

残念ながらバッタで作成したファイル内の合計をキャプチャし、これはあなたのスクリプト-FUを超えると、マスターは述べています。 :(

は、私はいくつかのオンラインのクラスを試してみたけど、彼らは助けている間、私は苦労し、私が実行して最高の学び見つけるよ...よく、あなたが知っている、

をExell内のデータを操作しようとしたが、 、およびメンターでの作業。私は...デビッドCaradinを助けたが、彼が引退だと棒で私を襲っているブラインドSholinモンクを見つけること

任意のヒントを試してみた?

+0

問題は、明らかに、あなたは誤って綴られていますShaolin ;-)。簡潔でテスト可能なサンプル入力と予想される出力を含むように質問を編集すれば、おそらく助けになるでしょう。 –

答えて

3

ので、第一および第二試みはいくつかの仕事が必要です - if/thenはあなたが思考しているように動作しないので...また、区切り文字の置換は、awkOFS組み込み変数を使用すると非常に簡単に処理できます。

awk 'BEGIN { OFS="," } $1 ~ /^Counter/ || $1 ~ /^IfInErrors/ || $1 ~ /^IfOutErrors/ { $1=$1; print > FILENAME ".csv" }' file.log 

このコードでは、「開始」または「^」という考え方を含むより限定的な正規表現で最初のフィールドをチェックします。それぞれのケースで、毎回 "$ 1〜"を繰り返さなければならないことに注意してください。これをオリジナルの "if文"に入れるにはこれも必要です。しかし...我々はまた、論理的かのなし一度にすべてのあなたのケースを処理するより簡潔な正規表現を構築することができます...

awk 'BEGIN { OFS="," } $1 ~ /^Counter|^If(In|Out)Errors/ { $1=$1; print > FILENAME ".csv" }' file.log 

OFS=","文はカンマに出力区切り文字を設定します。 $1=$1は実際には区切り文字の変更を入力行に適用します。未修飾のprint文は、現在の行バッファを出力します。 が目的のファイルに出力されます。

これは以下に私たちを取得します。

Counter,Name,port,1/1/x33,port,1/1/x34,port,1/1/x35,port,1/1/x36 
IfInErrors:,0,0,0,0 
IfOutErrors:,0,0,0,0 
Counter,Name,port,1/1/x37,port,1/1/x38,port,1/1/x39,port,1/1/x40 
IfInErrors:,**95**,0,0,0 
IfOutErrors:,0,0,0,0 

これはあなたの出力は異なっているが、それは私があなたのスクリプトから期待するものである - ここでは、すべての空白は単一のカンマに変換されるため。私はだと思います。実際にタブ区切りのファイルがありました。より多くのあなたがあなたの例の出力に持っているもののようなものになり

awk 'BEGIN { FS="\t"; OFS="," } $1 ~ /^Counter|^If(In|Out)Errors/ { $1=$1; print > FILENAME ".csv" }' file.log 

ので、あなたが見つけた場合、あなたは本当に私たちはBEGINセクション区切り文字の入力を指定することができます上記のすべてのカンマを望んでいません
Counter Name,port 1/1/x33,port 1/1/x34,port 1/1/x35,port 1/1/x36 
IfInErrors:,0,0,0,0 
IfOutErrors:,0,0,0,0 
Counter Name,port 1/1/x37,port 1/1/x38,port 1/1/x39,port 1/1/x40 
IfInErrors:,**95**,0,0,0 
IfOutErrors:,0,0,0,0 

単純なタブ区切りがなく、区切り文字の削除が必要な場合は、より複雑な正規表現をFSに使用できます。

あなたが必要とする残りの部分については、明らかにすることが役に立ちます。出力の例を示してください。特に、あなたの質問が現在0の合計値を求めているからです。 ENDで

$1 ~ /^If(In|Out)Errors/ { 
     for (i=2; i<=NF; i++) { 
       gsub(/\*/, "", $i) 
       if ($i == 0) { 
         z++ 
       } else { 
         nz++ 
         s += $i 
       } 
     } 
} 

そして何かを{}句と変更..うーん... 0役立つヒントがいくつカウンター....次の句のようなものでforループを使用することですのようなファイル名:

END || filename != FILENAME { 
     if (z || nz || s) { 
       print filename ": " z, nz, s 
       z=nz=s=0 
     } 
     filename=FILENAME 
} 
+0

うわー、私よりもはるかにクリーンです!マイケルありがとう。 –