【问题标题】:How to find the maximum value for the field by ignoring the lines with characters using awk?如何通过使用awk忽略带有字符的行来找到该字段的最大值?
【发布时间】:2020-11-25 22:44:40
【问题描述】:

由于我是awk 的新手,请帮助我提出您的建议。我尝试了以下命令来过滤最大值并分别忽略示例文本文件中的第一行和最后一行。当我单独尝试它们时它们会起作用。

我的查询:

我需要忽略文件的最后一行和前几行,然后需要使用 awk 为字段 7 取最大值。

我还需要忽略带有字符的行。谁能建议我两个同时使用这两个命令并获得所需输出的可能性。

示例文件:

Linux 3.10.0-957.5.1.el7.x86_64 (j051s784)      11/24/2020      _x86_64_        (8 CPU)

 

12:00:02 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty

12:10:01 AM   4430568  61359128     93.27   1271144  27094976  66771548     33.04  39005492  16343196      1348

12:20:01 AM   4423380  61366316     93.28   1271416  27102292  66769396     33.04  39012312  16344668      1152

12:30:04 AM   4406324  61383372     93.30   1271700  27108332  66821724     33.06  39028320  16343668      2084

12:40:01 AM   4404100  61385596     93.31   1271940  27107724  66799412     33.05  39031244  16344532      1044

06:30:04 PM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty

07:20:01 PM   3754904  62034792     94.29   1306112  27555948  66658632     32.98  39532204  16476848      2156

Average:      4013043  61776653     93.90   1293268  27368986  66755606     33.03  39329729  16427160      2005

使用的命令:

cat testfile | awk '{print $7}'  | head -n -1 | tail -n+7
awk 'BEGIN{a=   0}{if ($7>0+a) a=$7} END{print a}' testfile

预期输出:

Maximum value for the column 7 by excluding the lines wherever alphabet character is available

【问题讨论】:

  • tail -n+7 跳过前 6 行。这是故意的吗?
  • 在这里我尝试了 -n+7 以避免包含字母字符和空行的行。@RuudHelderman
  • 如果我将你的命令的点点滴滴汇集在一起​​,我似乎得到了你的要求:head -n-1 testfile | tail -n+7 | awk 'BEGIN{a=0}{if($7>0+a)a=$7}END{print a}' 输出:27555948

标签: awk


【解决方案1】:

第一个解决方案(通用解决方案): 在此处添加一个通用解决方案,其中将字段名称发送到 awk 变量(我们要寻找最大值) 它会自动从第一行找出它的字段编号并相应地工作。考虑到您的第一行具有您要查找的字段名称。

awk -v var="kbcached" '
FNR==1{
  for(i=1;i<=NF;i++){
   if($i==var){ field=i }
  }
  next
}
/kbmemused/{
  next
}
{
  if($2!~/^[AP]M$/){
    val=$(field-1)
  }
  else{
    val=$field
  }
}
{
  max=(max>val?max:val)
  val=""
}
END{
  print "Maximum value is:" max
}
' Input_file


第二个解决方案(仅根据显示的示例):您能否尝试以下操作,仅基于您显示的示例。我假设您想要列 kbcached 的字段值。

awk '
/kbmemfree/{
  next
}
{
  if($2!~/^[AP]M$/){
    val=$6
  }
  else{
    val=$7
  }
}
{
  max=(max>val?max:val)
  val=""
}
END{
  print "Maximum value is:" max
}
'  Input_file

【讨论】:

  • 是的,我正在寻找 kbcached @RavinderSingh13
  • @learnnewinfy,你确定你可以检查我的两个解决方案,如果这对你有帮助,请告诉我?
  • @learnnewinfy,如果您想跳过前 6 行,请尝试 tail -n+7 Input_file | awk....program(s) mentioned in solutions。但是我保留了一个条件来跳过像kbmemfree 这样的字符串之间的行,以跳过这些行。
  • 是的。您的解决方案符合我的预期。 @RavinderSingh13
【解决方案2】:
awk '$7 ~ ^[[:digit:]]+$/ && $1 != "Average:" { 
                      max[$7]="" 
              } 
     END      { 
                      PROCINFO["sorted_in"]="@ind_num_asc";
                      for (i in max) { 
                                       maxtot=i 
                                     } 
                      print maxtot 
               }' file    

一个班轮:

awk '$7 ~ /^[[:digit:]]+$/ && $1 != "Average:" { max[$7]="" } END { PROCINFO["sorted_in"]="@ind_num_asc";for (i in max) { maxtot=i } print maxtot }' file

使用 GNU awk,搜索字段 7 仅为数字且字段 1 不是“平均”的行:在这些情况下,创建一个以字段 7 作为索引的数组条目。最后,按索引升序对数组进行排序。循环遍历设置 maxtot 变量的数组。 max 数组中的最后一个条目将是最高的 kbcached,因此打印 maxtot

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2017-10-23
    • 2012-12-18
    • 2020-06-06
    相关资源
    最近更新 更多