如何使用awk或shell脚本打印不规则的文件格式

时间:2016-06-22 21:25:02

标签: bash shell unix awk sed

我的Linux服务器上有一个统计文件,每隔10秒就会更新名为“C1”,“C2_Detected”,“C3_Detected”的计数器。 C2和C3计数器在下一行还有一个额外的标题(即“检测到”),但C1没有。我需要阅读C2_DetectedC3_detected的值,并在C2_detectedC3_Detected非零时以下列格式打印输出。

输出应打印:日期,时间,名称以及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

我已尝试awk使用日期(即16-06-2016)作为记录分隔符,但它不起作用。请协助如何分隔记录,因为每条记录都是多行的。

输入文件格式,在10秒后以日期作为记录分隔符重复:

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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