如果否则,Awk NR:如何删除没有条目的表的节标题

如果否则,Awk NR:如何删除没有条目的表的节标题

我试图总结一张每天都在变化的数据表。我已经将该表汇总为仅显示条目大于 30 的行。

但是,有时原始表中的条目数不会超过 30 个。当发生这种情况时,我不需要摘要中的整个空白部分。然后我如何删除这些部分的整个标题?

理想情况下,如果所有 5 个部分中都没有条目,则不应打印任何行(或者只是打印一个字符串:“无:没有大于 30 的条目”,正如我试图做的那样)

包含 5 个部分的汇总表示例,summarished_output.txt:

=========================================================================================================
Month: Jun      

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun     

Counter Name                                06/05 14:00     06/05 13:00     06/05 12:00     06/05 11:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun      

Counter Name                                06/05 10:00     06/05 09:00     06/05 08:00     06/05 07:00
=========================================================================================================


=========================================================================================================
Month: Jun    

Counter Name                                06/05 06:00     06/05 05:00     06/05 04:00     06/05 03:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun      

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================

正如您所看到的,第三部分是空的,因为original_output.txt 文件中没有高于30 的条目。但是标头仍然存在。

我的摘要代码(有效):

awk '$1=="Month:"||$1==""||$1=="Counter"||(index($1, "=")!=0)||$3>=30|| $4>=30 || $5>=30||$6>=30' original_output.txt>>summarised_output.txt

我尝试删除标题(不起作用):

touch summarised_output_temp.txt
awk '{if ($1=="Month:"||$1==""||$1=="Counter"||(index($1, "=")!=0)||$3>=30|| $4>=30 || $5>=30||$6>=30) print $0}' original_output.txt >> summarised_output_temp.txt
if (((wc -l < summarised_output_temp.txt)==42))
then
echo "None: there is no entry larger than 30" >> summarised_output.txt
else
cat output_7_temp.txt>>summarised_output.txt
fi

尝试收到的错误:

line 3: ((: (wc -l output_7_temp.txt | awk {print $1})==42: syntax error: invalid arithmetic operator (error token is ".txt | awk {print $1})==42")

答案1

如果你有 GNU awk,你可以使用这个脚本:

awk -v RS='={105}[^=]*={105}' 'NF{print oRT,$0} {oRT=RT}' file

表头设置为多行记录分隔符RS。它由两个 105 个字符以及中间的任何字符组成=

该变量RT捕获每个记录的记录分隔符,并将其存储在变量中oRT,并在下一条记录处打印,前提是有一些元素要打印(使用 catch 进行捕获NF)。

答案2

创建可执行脚本test.awk,包含

awk '
  # { print "read " $0 }
  /^SYS/ {
    if (H) {
      if (F) {print F} else { F="\r\n\r\n"}
      print H; H=""}
    print
    next
  }
  /^./ {
    H=$0
    for (i=1; i<5; i++) {
      getline
      H = H "\r\n" $0
    }
    next
  }
' $@

并运行

test.awk original_output.txt

“/^SYS/ {”可以替换为任何可识别数据行的内容。

答案3

这个问题可以用 Perl 沿着这些思路来解决。

代码

perl -F'/^=+$/m' -lan -0777e '
   my($dashes) = /^(=+)$/m;
   shift @F; pop @F;
   while ( @F > 1 ) {
      my($h, $s) = splice @F, 0, 2;
      next if $s =~ /^(?:\h*\n)+$/;
      print join $dashes, q(), $h, $s, !@F ? q() : ();
   }
' input.txt

输出

=========================================================================================================
Month: Jun

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/05 14:00     06/05 13:00     06/05 12:00     06/05 11:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/05 06:00     06/05 05:00     06/05 04:00     06/05 03:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================

解释

  • 一口气输入: -0777选择珀尔使之成为可能。
  • 沿着破折号分割整个文件(现在被视为一个长字符串):/^=+$/米意味着给定行只包含重复的等于的地方就是我们分割文件的地方。
  • -A选项将使珀尔将分割后的部分填充到数组中@F
  • -nPerl 的选项将在读取下一条记录之前禁用自动打印,并且还会执行awk-类似于从输入读取的记录上的循环。
  • 首先,我们存储输入中的虚线。
  • 请注意,拆分操作将使第一个和最后一个元素为空,因此我们从@F在执行主要任务之前先进行数组。
  • 我们设置了一个 while 循环,它消耗 2 个元素(拼接)在某个时间从@Farray.First 是标题,第二个是部分。只要数组中至少还有 2 个元素,循环就会继续。
  • 关键点是决定跳过或不跳过处理标题/部分二重奏。当该部分仅包含空行或仅包含水平空白的行时,就会决定这一点(\H)。正则表达式是/^(?:\h*\n)+$/
  • 现在,如果该部分不为空,则仍然需要将标题/部分二重奏与破折号缝合在一起。我们记住,在最后一个标题/部分组合在一起时,我们需要添加破折号以进行四舍五入。

答案4

与奥利夫的答案类似,也许更简单一些:

gawk -v RS='=+\n' '
    NR % 2 == 0 {header = $0; next}
    /[^[:space:]]/ {printf "%s", RT header RT $0}
    END {print RT}
' output.txt 

使用一行=s 作为记录分隔符。标头是每个偶数记录。如果“内容”包含非空白字符,则“内容”不为空。

RT是一个 GNU awk 特定变量,包含“与 RS 表示的文本相匹配的输入文本,即记录分隔符。每次读取记录时都会设置它。”

相关内容