Rückreferenzierung in Awk-Regex

Rückreferenzierung in Awk-Regex

Ist dies in Awk möglich?:

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

Antwort1

Nicht im Standard awk(POSIX awkverwendet POSIX EREs, die keine Rückverweise unterstützen, und \1bedeutet das 0x1-Zeichen in awk, obwohlEs gibt einige Unklarheiten). Dies ist busybox awkjedoch möglich, indem Sie Folgendes verwenden:

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

(was das tun kann oder nicht (ob das "\\1"einem Literal oder dem 0x1-Zeichen entsprechen soll \1oder nicht angegeben werden soll) istunklar in der POSIX-Spezifikation. Meiner Meinung nach scheint es zu bedeuten, dass es mit einem 0x1-Zeichen übereinstimmen sollte, aber das /usr/xpg4/bin/shist beispielsweise unter Solaris 11, einem zertifizierten Betriebssystem (wo es \1stattdessen mit einem Literal übereinstimmt), nicht der Fall.

Für jeden dieser awkWerte können Sie für diesen bestimmten regulären Ausdruck einen anderen Ansatz wählen, etwa:

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

Wie oben erwähnt, unterstützen POSIX EREs keine Rückverweise. GNU sedverwendet -rEREs, aber das sind GNU EREs, die Rückverweise als Erweiterung des Standards unterstützen. Das bedeutet, dass

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

(oder dasselbe mit egrep) ist nicht portierbar. Allerdings:

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

ist POSIX und portierbar. POSIX BREs unterstützen Rückverweise, ebenso wie historische Implementierungen von grep. perlRegexps oder PCREs unterstützen ebenfalls Rückverweise, sodass Sie Folgendes tun können:

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

verwandte Informationen