提问人:miken32 提问时间:3/15/2018 最后编辑:miken32 更新时间:3/16/2018 访问量:113
使用多个分隔符时第一个字段为空
Empty first field when using multiple delimiters
问:
我正在尝试解析程序的输出,如下所示:
Status : OK (97 ms)
这些都是空格,没有制表符。我不知道该间距是否会在不同版本中保持一致,因此我想将空格和冒号视为分隔符。
我很清楚字段分隔符可以声明为任意复杂的正则表达式,所以我希望这会起作用:
echo " Status : OK (97 ms)" | awk -F'[ :]+' '/Status/{print $2}'
但事实并非如此;相反,它打印“Status”,并且是一个空字符串。$1
将其与内置分隔符的输出进行比较,其中前导分隔符似乎被忽略,并且是“状态”:$1
echo " Status : OK (97 ms)" | awk '/Status/{print $1}'
打印起来很容易,但它让我想知道我做错了什么,或者误解了什么?$3
我正在使用 GNU Awk 3.1.7
答:
因为,在样本输入中,字段分隔符在 之前,第一个字段为空,第二个字段为 。观察: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 标准中:
如果 FS 为 null 字符串,则未指定行为。
如果 FS 是单个字符:
一个。如果 FS 是 ,则跳过前导和尾随以及字符;字段应由一个或多个字符的集合分隔。
<space>
<blank>
<newline>
<blank>
<newline>
b.否则,如果 FS 是任何其他字符 c,则应分隔字段 通过每次出现 c。
否则,FS 的字符串值应被视为 扩展正则表达式。序列匹配的每次出现 扩展的正则表达式应分隔字段。
评论
FS
根据您对字段分隔符的定义,这就是字段解析的内容。为了更好地可视化它,让我们用逗号替换字段分隔符
$ awk '{gsub(/[ :]+/,",")}1' file
,Status,OK,(97,ms)
现在很明显,“状态”是字段 2。
下一个:(可选)将参数传递给脚本中的命令
评论