Referencia inversa en expresiones regulares Awk

Referencia inversa en expresiones regulares Awk

¿Es posible hacer esto en Awk?:

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

Respuesta1

No está en el estándar awk(POSIX awkusa ERE POSIX que no admiten referencias anteriores y \1significa el carácter 0x1 en awk, aunquehay algunas ambigüedades). Es posible busybox awkaunque use:

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

(lo que eso puede o no hacer (si "\\1"debe coincidir con un literal \1o el carácter 0x1 o no estar especificado) espoco claro en la especificación POSIX. En mi lectura, parece implicar que debe coincidir con un carácter 0x1, pero no es así /usr/xpg4/bin/shen Solaris 11, por ejemplo, que es un sistema operativo certificado (donde coincide en un literal \1))

Con any awk, para esa expresión regular en particular, podrías adoptar otro enfoque como:

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

Como se mencionó anteriormente, los ERE POSIX no admiten referencias anteriores. GNU sedusa -rERE, pero son GNU ERE que admiten referencias anteriores como una extensión del estándar. Lo que eso significa es que

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

(o lo mismo con egrep) no es portátil. Sin embargo:

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

es POSIX y portátil. Los BRE POSIX admiten referencias anteriores, al igual que las implementaciones históricas de grep. perlLas expresiones regulares o PCRE también admiten referencias anteriores, por lo que puede hacer:

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

información relacionada