2016-06-28 10 views
1

私のスキルを上回るプロジェクトがあります。私の最終目標は、処理されたデータを散布図にすることです。列をデータ行に転記する

 Counter Name  Port: 1/8/x1  Port: 1/8/x2  Port: 1/8/x3  Port: 1/8/x4 
    ================== ================ ================ ================ ================ 
     IfInOctets:   5470343   5520353   5628425   5685539 
     IfInUcastPkts:    8878    9029    9345    9512 
    IfInNUcastPkts:   17779   17755   17755   17755 
     IfInPktDrops:    0    0    0    0 
     IfInDiscards:   26657   26784   27100   27267 
     IfInErrors:    0    0    0    0 

Port number,IfInErrors 

に値:これを行うには、私はこのフォーマットからのログ出力を変換する必要があります。

不要なラベルを減らすために、私はawkと他のコマンドを繰り返し使用します。 。

for i in `ls *.log`; do 
    awk '/Counter Name|IfInDiscards/ {print $0}' $i.txt 
done 

(再び私のスキルレベルが「MUYのpequeñaである)コマンドは次のとおりです。

for i in `ls *.log`; do 
    awk '/Counter Name|IfInDiscards/ {print $0}' $i.txt 
done 

私は次のクリーンな柱状のデータを私に残しsed

sed -i 's/Counter Name//g' *.txt #Delete Counter name and IfInDiscards 
sed -i 's/IfInErrors://g' *.txt 
sed -i 's/Port: //g'    #Eliminate unnecessary Port: and space 
sed -i 's/ */ /g' 
sed -i "s/ /,/g"     #Convert white space to commas 

を使用して不要なデータを破棄します。

Column1,column2,Column3,Column4,Column5 
Row1 ,1/8/x1,1/8/x2,1/8/x3,1/8/x4 
Rowd2 ,0,0,0,0 

私の次の項目は、先行するコンマ(Column1)を削除することです。

Column1,column2,Column3,Column4 
Row1 1/8/x1,1/8/x2,1/8/x3,1/8/x4 
Row2 0,0,0,0 

私にとっては、このフォーマット(連結列+行データ、コマンドと列+行データ)にデータを取得するのが大変です。

Col1+row1,col1+row2 
Col2+row1,col2+row2 

。 。 end

常に4つの列と100行までです。

私はこれをコードに変換する方法はわかりません。

いつものように、私は自分のスキルレベルを構築したいと思うように、単純な「誰かが私のためにこれを行うことができる」アプローチを探しているだけではありません。コピー+ペーストは速いが、私は学ばない。

言われているとおり、私は指針を探しています。

+0

これをシェルですべて実行しようとしていますか? – JimmyJames

+0

はい、私です。私はPythonを学んでいますが、話し合うピアがなければ遅くなり、仕事はいつもかなり忙しいです。 –

答えて

1

これはすべて、単一のawkコマンドで実行できます。配列を使用して、最初の行からポート番号を保持します。

for file in *.log; do 
    awk '/Counter Name/ { for (col = 4; col <= NF; col += 2) port[col/2] = $col } 
     /IfInErrors/ { for (col = 2; col <= NF; col++) printf("%s,%d\n", port[col], $col) }' < "$file" 
done 

awkスクリプトの最初の行は、ポート番号の見出しの行に一致します。列を2つループし、ポート番号を含む配列を作成します。

2行目は、入力エラー値を含む行と一致します。次に、残りの列を通過し、上記の配列のポート番号の後にその列の値が出力されます。

複数の行の値を列に転記できるようにするには、必要なカウンタが表示されたらすぐに印刷するのではなく、配列を使用してすべての値を保存する必要があります。

awk '/Counter Name/ { for (col = 4; col <= NF; col += 2) port[col/2] = $col; maxcols = NF/2 } 
     /IfInErrors/ { for (col = 2; col <= NF; col++) inErrors[col] = $col } 
     /IfInOctets/ { for (col = 2; col <= NF; col++) inOctets[col] = $col } 
     END { for (col = 2; col <= maxcols; col++) printf("%s,%d,%d\n", port[col], inErrors[col], inOctets[col]); } 
    ' < "$file" 
done 

あなたは出力に含める値のそれぞれについて/IfInErrors//IfInOctets/のような行を繰り返すことができます。値を保存する配列の名前を変更し、ENDブロックのprintfに追加します。

+0

ありがとうございます。意味を解読するのに少し時間がかかるでしょうが、スクリプトはグレードになります。すぐにスクリプトを試してみましたが、うまくいきました。再びありがとう。 –

+0

4番目の列は正しく処理されていません。理由を理解できません。 パターンは次のようになります 行をきれいに移した行を行に変換します。 1行分エグジットします。 1/1/x3,0 1/1/x2,0 1/1/x1,0 、01/X4 \t \t \t <===そして、このパターを繰り返します。 使用している構文に慣れていないため、ログをステップスルーできません。もう一度手伝ってもらえますか? Regard –

+0

質問のサンプルファイルでテストしてみましたが、うまくいきました。あなたが使用している実際のファイルには何か異なるものがなければなりません。 – Barmar