2009-10-12 5 views
22

Dies scheint wie es sein sollte Schmutz einfach, aber das awk gensub/gsub/sub Verhalten war immer unklar für mich, und jetzt kann ich es einfach nicht tun, was zu tun Dokumentation sagt, dass es tun sollte (und welche Erfahrung mit einer Zillion anderer ähnlicher Werkzeuge schlägt, sollte funktionieren). Insbesondere möchte ich von einer Regex in der Ersetzungszeichenfolge auf "erfasste Gruppen" zugreifen. Hier ist, was ich denke, die awk Syntax sein sollte:GNU awk: Zugriff auf erfasste Gruppen im Ersetzungstext

awk '{ gsub(/a(b*)c/, "Here are bees: \1"); print; }' 

Das sollte drehen „abbbc“ in „Hier sind Bienen: bbb“. Es geht nicht, zumindest nicht für mich in Ubunutu 9.04. Stattdessen wird das "\ 1" als ein A wiedergegeben; das heißt, das Zeichen mit Code 1. Nicht was ich will, natürlich. Wie mache ich das?

Danke.

Antwort

20
echo abbc | awk '{ print gensub(/a(b*)c/, "Here are bees: \\1", "g", $1);}' 

Siehe Handbuch here den Unterschied zwischen gsub und gensub

+3

Auch nicht nur anders gsub und gensub verhalten gegen Wert zurückzukehren, sondern die ganze \ 1 bis \ 9 Funktion * nur * mit gensub funktioniert. – Pointy

+0

Versuchen Sie 'echo xxxabbcxxx' - die awk" Lösung "bricht –

+0

@Alesandr, fühlen Sie sich frei, eine neue vorzuschlagen –

19

Pro die gaffen Handbuch

gensub bietet ein zusätzliches Merkmal zu sehen, die nicht in Unter oder gsub ist: die Fähigkeit, um Komponenten eines Regexp im Ersetzungstext anzugeben. Diese erfolgt durch Klammern im regexp unter Verwendung der Komponenten und dann Spezifizierungs ‚\ N‘ im Ersatz Text zu markieren, wobei N eine Ziffer von 1 bis 9.

Sie gensub verwenden müssen, Sie müssen "g" angeben, und Sie müssen das Ergebnis von Gensub greifen, da es in-Place nicht ändert.

awk '{ r = gensub(/a(b*)c/, "Here are bees: \\1", "g"); print r; }'