Awk 正規表現における後方参照

Awk 正規表現における後方参照

Awk でこれを行うことは可能ですか?

echo "eoe" | sed -nr '/^(.*)o\1$/p'

答え1

標準ではありませんawk(POSIXはawkPOSIX EREを使用しますが、これは後方参照をサポートしておらず、\1awkでは0x1文字を意味します。曖昧な点もある) ただし、以下を使用することで可能ですbusybox awk:

busybox awk '$0 ~ "^(.*)o\\1$"'

(それが何をするかしないか("\\1"リテラルに一致するか\1、0x1文字に一致するか、指定しないか)はPOSIX仕様では不明瞭私の解釈では、0x1 文字に一致するはずであると思われますが、認定 OS である Solaris 11 では一致しません/usr/xpg4/bin/sh(代わりにリテラルに一致します\1))

any の場合awk、その特定の正規表現に対して、次のような別のアプローチを取ることができます。

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

上で述べたように、POSIX EREは後方参照をサポートしていません。GNUはsedERE-rを使用していますが、それは標準の拡張として後方参照をサポートするGNU EREです。つまり、

grep -Ex '(.*)o\1'

(または と同じegrep) は移植性がありません。ただし、

grep -x '\(.*\)o\1'

POSIX であり、移植性があります。POSIX BRE は、.regexps の歴史的な実装と同様に、後方参照をサポートしていますgrepperlまたは PCRE も後方参照をサポートしているため、次の操作を実行できます。

perl -lne 'print if /^(.*)o\1$/'

関連情報