![如何使用不支持反向引用的 POSIX awk“雕刻出”匹配值](https://linux22.com/image/216779/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E4%B8%8D%E6%94%AF%E6%8C%81%E5%8F%8D%E5%90%91%E5%BC%95%E7%94%A8%E7%9A%84%20POSIX%20awk%E2%80%9C%E9%9B%95%E5%88%BB%E5%87%BA%E2%80%9D%E5%8C%B9%E9%85%8D%E5%80%BC.png)
给定输入,例如:
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
来删除最后一个字段之后的[
和]
字符:awk
sed
$ awk '{ print $NF }' file | tr -d '[]'
342
8349
$ sed 's/.* //' file | tr -d '[]'
342
8349
另请注意,sed -E
POSIX 尚不支持这一点。