I need to escape some characters from my awk (GNU Awk 4.2.0) input - { with \{, [ with \[ and | with \|. I accomplished that with three gsub calls:

for (i = 2; i <= NF; i++) {
    gsub(/{/, "\\{", $i)
    gsub(/\[/, "\\[", $i)
    gsub(/\|/, "\\|", $i)

How can I combine those three calls into one? Something like

gsub(/([{[|])/, "\\\1", $i)
  • Which awk are you using? – Michael Homer Feb 22 '18 at 21:34
  • The one from cygwin. Looks like it is gawk: $ awk -V GNU Awk 4.2.0, API: 2.0 (GNU MPFR 3.1.6-p1, GNU MP 6.1.2) – rambius Feb 22 '18 at 21:36

You can use & in the replacement to refer to the matched text:

$ awk '{gsub(/[[{|]/, "\\\\&", $0); print}' <<<"abc { | [ def"
abc \{ \| \[ def

That's just a regular [...] character class with [, |, and { in it in the pattern, and a sufficiently-escaped backslash followed by & in the replacement. You do need all of them.

For more complex patterns gawk has a gensub function that lets you make references to part of the text, like \\1, but you don't need that here. All POSIX-compatible awks support the & behaviour for including the entire matched substring in the replacement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.