Backreference no awk regex

3

É possível fazer isso no Awk?:

echo "eoe" | sed -nr '/^(.*)o$/p'
    
por Ignacio 26.04.2017 / 15:50

1 resposta

6

Não está no padrão awk (POSIX awk usa POSIX EREs que não suportam referências anteriores e significa o caractere 0x1 no awk, embora existem algumas ambiguidades ). É possível com busybox awk usando:

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

(o que pode ou não fazer (se "\1" deve coincidir com um literal ou o caracter 0x1 ou não ser especificado) não está claro na especificação POSIX. Na minha leitura, parece implicar que deve corresponder a uma 0x1, mas não com /usr/xpg4/bin/sh no Solaris 11, por exemplo, que é um sistema operacional certificado (onde corresponde a um literal ))

Com qualquer awk , para esse regexp específico, você poderia adotar outra abordagem como:

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

Como mencionado acima, os POSIX EREs não suportam referências anteriores. O GNU sed com -r usa EREs, mas isso é o GNU EREs que suporta referências anteriores como uma extensão do padrão. O que isso significa é que

grep -Ex '(.*)o'

(ou mesmo com egrep ) não é portátil. No entanto:

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

é POSIX e portátil. POSIX BREs suportam referências anteriores, assim como implementações históricas de grep . perl regexps ou PCREs também suportam referências anteriores para que você possa fazer:

perl -lne 'print if /^(.*)o$/'
    
por 26.04.2017 / 15:58