我试图解析程序的输出,如下所示:
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
答案 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
对于默认字段分隔符,将忽略前导空格和尾随空格。如果使用自定义字段分隔符,则忽略前导和尾随分隔符 。这在POSIX standard:
中有记录
如果FS为空字符串,则行为未指定。
如果FS是单个字符:
一个。如果FS为
<space>
,请跳过前导和尾随<blank>
和<newline>
字符;字段应由一个或多个<blank>
的集合分隔 或<newline>
个字符。湾否则,如果FS是任何其他字符c,则应分隔字段 每次出现c。
- 醇>
否则,FS的字符串值应视为a 扩展正则表达式。每次出现一个序列匹配 扩展正则表达式应划分字段。
答案 1 :(得分:1)
使用您对字段分隔符的定义,这是字段解析的内容。为了更好地可视化,让我们用逗号替换字段分隔符
$ awk '{gsub(/[ :]+/,",")}1' file
,Status,OK,(97,ms)
现在很清楚“状态”是字段2.