使用多个分隔符时清空第一个字段

时间:2018-03-14 18:54:13

标签: awk delimiter

我试图解析程序的输出,如下所示:

  Status       : OK (97 ms)

这些都是空格,没有标签。我不知道这个间距是否会在不同的版本中保持一致,所以我想将空格冒号视为分隔符。

我很清楚字段分隔符可以声明为任意复杂的正则表达式,所以我希望这可行:

echo "  Status       : OK (97 ms)" | awk -F'[ :]+' '/Status/{print $2}'

但事实并非如此;相反,它打印"状态",$1是一个空字符串。

将此与内置分隔符的输出进行比较,其中前导分隔符似乎被忽略,而$1是"状态":

echo "  Status       : OK (97 ms)" | awk '/Status/{print $1}'

很容易打印$3,但它让我想知道我做错了什么,或者误解了什么?

我使用的是GNU Awk 3.1.7

2 个答案:

答案 0 :(得分:1)

因为,在示例输入中,字段分隔符位于Status之前,第一个字段为空,第二个字段为Status。观察:

$ echo "  Status       : OK (97 ms)" | awk -F'[ :]+' '/Status/{print $2}'
Status
$ echo "Status       : OK (97 ms)" | awk -F'[ :]+' '/Status/{print $2}'
OK

一种选择是将:(设置为字段分隔符。在这种情况下,无论是否存在前导空格,第二个字段都将包含$2

$ echo "  Status       : OK (97 ms)" | awk -F'[:(]+' '/Status/{print $2}'
 OK 
$ echo "Status       : OK (97 ms)" | awk -F'[:(]+' '/Status/{print $2}'
 OK 

另一种选择是保留字段分隔符,但在打印前消除前导空格:

$ echo "  Status       : OK (97 ms)" | awk -F'[ :]+' '{sub(/^ +/,"")} /Status/{print $2}'
OK
$ echo "Status       : OK (97 ms)" | awk -F'[ :]+' '{sub(/^ +/,"")} /Status/{print $2}'
OK

Awk和前导或尾随字段分隔符

对于默认字段分隔符,将忽略前导空格和尾随空格。如果使用自定义字段分隔符,则忽略前导和尾随分隔符 。这在POSIX standard

中有记录
  
      
  1. 如果FS为空字符串,则行为未指定。

  2.   
  3. 如果FS是单个字符:

         

    一个。如果FS为<space>,请跳过前导和尾随<blank><newline>   字符;字段应由一个或多个<blank>的集合分隔   或<newline>个字符。

         

    湾否则,如果FS是任何其他字符c,则应分隔字段   每次出现c。

  4.   
  5. 否则,FS的字符串值应视为a   扩展正则表达式。每次出现一个序列匹配   扩展正则表达式应划分字段。

  6.   

答案 1 :(得分:1)

使用您对字段分隔符的定义,这是字段解析的内容。为了更好地可视化,让我们用逗号替换字段分隔符

$ awk '{gsub(/[ :]+/,",")}1' file

,Status,OK,(97,ms)

现在很清楚“状态”是字段2.