GNU awk: доступ к захваченным группам в замещающем тексте

Кажется, это должно быть очень просто, но поведение awk gensub / gsub / sub всегда было для меня непонятным, и теперь я просто не могу заставить его делать то, что говорится в документации (и какой опыт работы с огромным количеством другие подобные инструменты должны работать). В частности, я хочу получить доступ к «захваченным группам» из регулярного выражения в строке замены. Вот каким, я думаю, должен быть синтаксис awk:

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

Это должно превратить «abbbc» в «Вот пчелы: bbb». Это не так, по крайней мере, для меня в Убунуту 9.04. Вместо этого "\ 1" отображается как ^ A; то есть символ с кодом 1. Конечно, не то, что я хочу. Как мне это сделать?

Спасибо.


person Pointy    schedule 12.10.2009    source источник


Ответы (2)


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

См. Руководство здесь, чтобы увидеть разницу между gsub и gensub.

person Community    schedule 12.10.2009
comment
Кроме того, не только gsub и gensub ведут себя по-разному в отношении возвращаемого значения, но и вся функция от \ 1 до \ 9 only работает с gensub. - person Pointy; 12.10.2009
comment
Попробуйте echo xxxabbcxxx - решение awk ломается - person Aleksandr Levchuk; 23.06.2011
comment
@Alesandr, не стесняйтесь предлагать новую - person ; 27.06.2011
comment
@AleksandrLevchuk Ваш пример работает именно так, как ожидалось. Я не вижу ничего плохого в этом решении. Он выполняет замену, а затем возвращает полные переменные. - person Sparhawk; 28.10.2016
comment
Мне смешно видеть, как кто-то заявляет, что язык не работает из-за того, что они не понимали синтаксис или не читали руководство! - person Medievalist; 05.04.2017

Согласно руководству gawk

gensub предоставляет дополнительную функцию, недоступную в sub или gsub: возможность указывать компоненты регулярного выражения в тексте замены. Это делается с помощью скобок в регулярном выражении для обозначения компонентов и последующего указания «\ N» в тексте замены, где N - это цифра от 1 до 9.

Вы должны использовать gensub, вы должны указать "g" и вы должны получить результат gensub, поскольку он не изменяется на месте.

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