awk 正则表达式中的反向引用

Ign*_*cio 4 sed awk regular-expression

是否可以在 awk 中执行此操作?:

echo "eoe" | sed -nr '/^(.*)o\1$/p'
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 11

不是标准的awk(POSIXawk使用不支持反向引用的 POSIX ERE,并且\1表示 awk 中的 0x1 字符,尽管存在一些歧义)。这是可能的busybox awk,虽然使用:

busybox awk '$0 ~ "^(.*)o\\1$"'
Run Code Online (Sandbox Code Playgroud)

(在 POSIX 规范中,可能会或可能不会做什么("\\1"应该匹配文字\1或 0x1 字符还是未指定)不清楚。在我的阅读中,它似乎暗示它应该匹配 0x1 字符,但它不与/usr/xpg4/bin/sh例如在 Solaris 11 上,这是一个经过认证的操作系统(它与文字匹配\1))

对于 any awk,对于该特定的正则表达式,您可以采用另一种方法,例如:

awk 'length % 2 && \
       substr($0, (length+1)/2, 1) == "o" && \
       substr($0, 1, (length-1)/2) == substr($0, (length+3)/2)'
Run Code Online (Sandbox Code Playgroud)

如上所述,POSIX ERE 不支持反向引用。GNU sedwith-r使用 ERE,但这是支持反向引用作为标准扩展的 GNU ERE。这意味着什么

grep -Ex '(.*)o\1'
Run Code Online (Sandbox Code Playgroud)

(或与 相同egrep)不可移植。然而:

grep -x '\(.*\)o\1'
Run Code Online (Sandbox Code Playgroud)

是 POSIX 和可移植的。POSIX BRE 确实支持反向引用,就像grep. perlregexp 或 PCRE 也支持反向引用,因此您可以执行以下操作:

perl -lne 'print if /^(.*)o\1$/'
Run Code Online (Sandbox Code Playgroud)