如果语句匹配,awk将变量设置为行

时间:2016-06-03 14:07:50

标签: awk

我有以下文字......

BIOS Information
Manufacturer               : Dell Inc.
Version                    : 2.5.2
Release Date               : 01/28/2015

Firmware Information
Name                       : iDRAC7
Version                    : 2.21.21 (Build 12)

Firmware Information
Name                       : Lifecycle Controller 2
Version                    : 2.21.21.21

...通过管道输入以下awk语句...

awk '{ if ($1" "$2 == "BIOS Information") var=$1} END { print var }'

在这种情况下,这将输出'BIOS'。 我想查找'BIOS Information',然后设置第三个字段,两行,所以在这种情况下'var'将等于'2.5.2'。有没有办法用awk做到这一点?

编辑: 我尝试了以下方法:

awk ' BEGIN {
FS="[ \t]*:[ \t]*";
}
NF==1 {
  sectname=$0;
}
NF==2 && $1 == "Version" && sectname="BIOS Information" {
  bios_version=$2;
}
END {
  print bios_version;
}'

上面的文字给了我'2.21.21.21'。可以修改它以便在“BIOS信息”之后给我第一个“版本”吗?

3 个答案:

答案 0 :(得分:4)

如果您有多个部门名称和/或字段顺序发生变化,以下脚本可能会有些过分,但它很强大。

BEGIN {
  FS="[ \t]*:[ \t]*";
}
NF==1 {
  sectname=$0;
}  
NF==2 && $1 == "Version" && sectname=="BIOS Information" {
  bios_version=$2;
} 
END {
  print bios_version;
}

首先,我们设置输入字段分隔符,以便单词不会分成不同的字段。接下来,我们检查当前行是段名还是键值对。如果是部分名称,请将sectname设置为部分名称。如果它是键值对,则当前节名称为" BIOS Information"关键是"版本"然后我们设置bios_version

答案 1 :(得分:3)

按要求回答问题

awk -v RS= '
/^BIOS Information\n/ {
   for(i=1;i<=NF;++i) { if ($i=="Version") { var=$(i+2); exit } }
}
END { print var }
' file
  • -v RS=awk置于段落模式中,以便每次非空行都成为单个记录。

  • /^BIOS Information\n/然后只匹配第一行等于&#34; BIOS信息&#34;的记录(段落)。

  • 每个段落在内部仍然被任何空白行(awk的默认行为)拆分为字段,因此for循环遍历所有字段,直到找到文字为止Version,将 2nd 字段分配给变量(因为:被解析为单独的字段)并退出,此时变量值将打印在{ {1}}阻止。

    • 注意:在下面的更新中可以找到更健壮,更完整的提取版本号的方法(此处的字段循环方法可能会产生误报,并且只会报告第一个(空白) -separated)版本字段的标记)。
根据以后出现的要求

更新

每个段落的版本号采取行动并创建个别变量

END

通过样本输入,可以得到:

awk -v RS= '

  # Helper function that that returns the value of the specified field.
  function getFieldValue(name) {
    # Split the record into everything before and after "...\n<name>   : "   
    # and the following \n; the 2nd element of the array thus created
    # then contains the desired value.
    split($0, tokens, "^.*\n" name "[[:blank:]]+:[[:blank:]]+|\n")
    return tokens[2]
  }  

  /^BIOS Information\n/ {
     biosVer=getFieldValue("Version")
     print "BIOS version = " biosVer
  }

  /^Firmware Information\n/ {
    firmVer=getFieldValue("Version")
    print "Firmware version (" getFieldValue("Name") ") = " firmVer 
  }

' file

答案 2 :(得分:0)

假设:

$ echo "$txt"
BIOS Information
Manufacturer               : Dell Inc.
Version                    : 2.5.2
Release Date               : 01/28/2015

Firmware Information
Name                       : iDRAC7
Version                    : 2.21.21 (Build 12)

Firmware Information
Name                       : Lifecycle Controller 2
Version                    : 2.21.21.21

你可以这样做:

$ echo "$txt" | awk '/^BIOS Information/{f=1; printf($0)} /^Version/ && f{f=0; printf(":%s\n", $3)}'
BIOS Information:2.5.2