2016-06-22 5 views
0

10秒ごとに "C1"、 "C2_Detected"、 "C3_Detected"という名前のカウンターを更新するLinuxサーバーの統計ファイルがあります。 C2およびC3カウンタには次の行に追加の見出し(つまり「検出」)がありますが、C1にはその見出しがありません。私はC2_DetectedC3_detectedの値を読んで、C2_detectedC3_Detectedがゼロでないときに、以下の形式で出力を印刷する必要があります。awkまたはシェルスクリプトを使用して不規則なファイル形式をプリントする方法

日付、時刻、名前、C2_DetectedまたはC3_Detectedのいずれかの値が出力されます。

たとえば、17:37:41のC3_Detected値は4です。したがって、出力は次のようになります。

16-06-21 Name   C1 C2  C3 
           detected detected 
17:37:41 monthly_output 319 0   4 

Iレコードセパレータとして(すなわち16-06-2016)awk使用して日付を試みたが、それは動作しません。各レコードが複数行であるため、レコードをどのように区切るかをお手伝いしてください。

レコードセパレータとして日付と10秒後に繰り返される入力ファイル形式:奇妙けどOK

16-06-21 Name    C1   C2  C3 
            detected detected 
17:37:41 daily_output  1144  0   0 
      monthly_output  319  0  4 
      yearly__output 533  0   0 
16-06-21 Name    C1  C2   C3 
            detected  detected 
17:37:41 daily_output  1144  3  0 
      monthly_output  319   0  0 
      yearly__output 533  0  0 
+1

質問の書式設定に先行する4つのスペースを含むファイル入力をコード環境などに置くと役立つかもしれません。スペースが質問の中でどこに関連しているのか、改行はどこにありますか?ありがとう。 – Dilettant

+0

あなたはねじれた入力フォーマットのために苦労していますが、同様にねじれた出力フォーマットを作りたいですか? CSVを出力してExcelにインポートしたり、簡単に操作できるのはなぜですか? –

答えて

1

awk '{ 
    if($2=="Name"){ 
    date=$1 
    start=NR 
    first=$0 
    } 
    else if(start>0){ 
    if(NR==(start+1)){ 
     second=$0 
    } 
    else if(NR==(start+2)){ 
     time=$1 
    } 
    } 
    if(start>0 && NR>=(start+2) && ($4>0 || $5>0)){ 
    if(time!=$1){ 
     $5=$4;$4=$3;$3=$2;$2=$1 
    } 
    printf "%s\n%s\n%s %s\t%s\t%s\t%s\n", first,second,time,$2,$3,$4,$5 
    } 
}' testfile 

16-06-21 Name    C1   C2  C3 
            detected detected 
17:37:41 monthly_output 319 0 4 
16-06-21 Name    C1  C2   C3 
            detected  detected 
17:37:41 daily_output 1144 3 0 
+0

2つまたは3つの 'period_output'行にC2またはC3が0より大きい場合、出力がどのように表示されるのでしょうか?質問はそのことを示していません。 –

+0

上記のコードは正常に動作していますが、if(time!= $ 1)$ 5 = $ 4 ......またはコード内でこれを使用していることを確認する必要があることを説明することができます –

+0

time = $ 1なら、それは毎日の出力行です。 $ 2 = "daily_output"などですが、毎月および毎年の出力行では、$ 1 = "monthly_output"または "yearly_output"です。すべてのawkフィールドが1つ上にシフトされます。代わりに、次のようにすることもできます:if time!= $ 1 then printf ... time、$ 1、$ 2、$ 3、$ 4(2,3,4,5の代わりに) – webb

1

私はあなたの足に自分自身を撮影支援するつもりはありません入力フォーマットと同じように解析するのと同じような出力フォーマットを生成することによって、代わりにこれを試してください:

$ cat tst.awk 
BEGIN { OFS="," } 
/^[0-9-]+[[:space:]]/ { 
    date = $1 
    names[1] = "Date" OFS "Time" 
    for (i=2;i<=NF;i++) { 
     names[i] = $i 
    } 
    nf = NF 
    next 
} 
NF==2 { 
    if (NR==2) { 
     for (i=1;i<=NF;i++) { 
      names[(nf-NF)+i] = names[(nf-NF)+i] "_" $2 
     } 
     for (i=1; i<=nf; i++) { 
      printf "%s%s", names[i], (i<nf?OFS:ORS) 
     } 
    } 
    next 
} 
{ 
    if (NF==nf) { 
     time = $1 
    } 
    else { 
     $0 = time FS $0 
    } 
    if (($NF != 0) || ($(NF-1) != 0)) { 
     $1 = $1 
     print date, $0 
    } 
} 

$ awk -f tst.awk file 
Date,Time,Name,C1,C2_detected,C3_detected 
16-06-21,17:37:41,monthly_output,319,0,4 
16-06-21,17:37:41,daily_output,1144,3,0 

$ awk -f tst.awk file | column -s, -t 
Date  Time  Name   C1 C2_detected C3_detected 
16-06-21 17:37:41 monthly_output 319 0   4 
16-06-21 17:37:41 daily_output 1144 3   0 
関連する問題