11

I'm parsing come legacy C-code using grep and sed and when trying to replace square brackets, something strange happened.

The following code to replace square opening brackets works fine:

$ echo "xyx[xzx]xyx" | sed 's|[\[]| |g'

results in:

xyx xzx]xyx

When I now add \] to the string to sed, to also replace square closing brackets, it stops working:

$ echo "xyx[xzx]xyx" | sed 's|[\[\]]| |g'

now results in:

xyx[xzx]xyx

As far as I know, this is the proper way to escape square brackets.

What am I doing wrong?

I'm running this on a Ubuntu 14.04 machine.

NZD
  • 1,780
  • 2
  • 20
  • 29

1 Answers1

14

You don't even need to escape:

echo "xyx[xzx]xyx" | sed 's|[][]| |g'
xyx xzx xyx

However keep in mind that order of ] then [ is important here.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 3
    This is because if `]` is the first character in the character class, it doesn't need excaping, as in `[]abc]` or, as pictured, `[][]` – djhaskin987 Jan 15 '15 at 21:47
  • @anubhava I tried it and it works. Thanks. There however still remain 2 things nagging. 1. Why can I both use `[` and `\[` to represent the square opening bracket and 2. How to include both `]` and `-` in a character class. – NZD Jan 17 '15 at 19:44
  • 2
    @Geert The answer to the first nagging issue is simple: A backslash is not a special character inside a character class. The sequence `\[` represents both characters. – NZD Jan 17 '15 at 19:52
  • For replacing `-` with `[` and `]` you can use: `echo "xyx[xzx]xyx-abc" | sed 's|[][-]| |g'` – anubhava Jan 18 '15 at 05:11
  • I still can't undestand why `[[]]` is treated differently than `[][]`? – IC_ Feb 03 '21 at 09:19
  • 1
    @Hergott `[[]]` is interpreted as `[[]` (match any of the one-character list `[`) followed by `]`. – Dan Stahlke Mar 06 '21 at 06:38
  • It will find both `[` and `]` – anubhava Mar 06 '21 at 07:02
  • Okay, but `echo "xyx[xzx]xyx" | sed 's|[][]| |g'` actually does work. So how can this be explained? The answer doesn't shine light on that. – trollkotze Aug 05 '21 at 20:41
  • 2
    Ah, now I see. I'm stupid: '[][]' is of course a group (enclosed with '[' and ']), containing ']' and '['. – trollkotze Aug 05 '21 at 20:44