如何使用不支持反向引用的 POSIX awk“雕刻出”匹配值

如何使用不支持反向引用的 POSIX awk“雕刻出”匹配值

给定输入,例如:

input value #001 is [342]
input value #002 is [8349]

如何提取 [...] 内的值,以便输出如下?

342
8349

对于支持反向引用(例如“\1”)的正则表达式来说,这应该很容易。但使用 ERE 的 POSIX awk 不支持这一点。

例如,POSIX sed 支持反向引用,因此:

<input sed -E 's/^.*\[([[:digit:]]+)\].*$/\1/'

如何在 POSIX awk 中执行此操作?

答案1

您可以使用match()which 设置RSTART匹配的开头及其RLENGTH长度(它还会返回RSTART; 或如果没有匹配则返回 0):

awk 'match($0, /\[[[:digit:]]+\]/) {
       print substr($0, RSTART, RLENGTH)
     }'

或者:

awk 'match($0, /\[[[:digit:]]+\]/) {
       print substr($0, RSTART+1, RLENGTH-2)
     }'

如果您只想要不带括号的数字。

请注意,mawk 不支持 POSIX 字符类,并且[[:digit:]]在某些系统的某些区域设置中匹配比 0123456789 更多的十进制数字。[0123456789]如果您只想匹配这些(而不是[0-9]),请使用。

[digits]请注意,如果一行中出现多次,该awk代码将返回第一个,而您的变体将返回最后一个(因为开始时sed贪婪)。.*

答案2

以下命令用于gsub删除每行输入的最后一个字段中的所有[]字符,然后打印该字段:

$ awk '{ gsub("[][]", "", $NF); print $NF }' file
342
8349

与 类似sed,通过删除每行上最后一个空格字符之前的所有内容,然后从剩下的内容中删除[and :]

$ sed -e 's/.* //' -e 's/[][]//g' file
342
8349

或者,使用或tr来删除最后一个字段之后的[]字符:awksed

$ awk '{ print $NF }' file | tr -d '[]'
342
8349
$ sed 's/.* //' file | tr -d '[]'
342
8349

另请注意,sed -EPOSIX 尚不支持这一点。

相关内容