Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm running this command in a bash shell on Ubuntu 12.04.1 LTS. I'm attempting to remove both the [ and ] characters in one fell swoop, i.e. without having to pipe to sed a second time.

I know square brackets have special meaning in a regex so I'm escaping them by prepending with a backslash. The result I was expecting is just the string 123 but the square brackets remain and I'd love to know why!

~$ echo '[123]' | sed 's/[\[\]]//'
share|improve this question
What I'm trying to ultimately achieve is to assign whatever's between the square brackets to a bash variable for use elsewhere in my bash script, so if there's a better way to achieve that (by using awk, maybe?), please let me know. – Xhantar Jan 11 '13 at 10:40
Just adding as a comment: You can use bash's PE feature as in: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2 – val0x00ff Jan 11 '13 at 11:08
@val0x00ff - Pure bash substitution.. thanks! :) Learned something new. – Xhantar Jan 11 '13 at 12:13
up vote 8 down vote accepted

I'm not sure why that doesn't work but this does:

echo '[123]' | sed 's/\(\[\|\]\)//g'

or this:

echo '[123]' | sed -r 's/(\[|\])//g'

You can also try a different approach and match the string inside the brackets (assuming the string can be matched easily and is not defined by the brackets):

echo '[123]' | egrep -o "[0-9]+"

I'm having the same troubles with your original regex using grep so I suspect this is not just a sed thing.

Weirdly, these produce different results but one of them matches what you want:

echo '[123]' | egrep -o '[^][]+'

echo '[123]' | egrep -o '[^[]]+'

Applying this to your original sed (and adding the /g modifier so it removes both brackets):

echo '[123]' | sed 's/[][]//g'
share|improve this answer
Your 3rd approach (egrep -o...) looks like the cleanest solution to my problem. I'll only ever have integers in between the square brackets (and sorry, I should have mentioned that in my question) so I shouldn't run into any oddities I think. Thanks! – Xhantar Jan 11 '13 at 12:20
You can also use tr: echo '[123]' | tr -d '[]' - avoids regexp confusions about escaping. – James O'Gorman Jan 11 '13 at 12:53
@James O'Gorman - Interesting. For some reason I thought that tr can only translate one character max at a time, but I was wrong. Thanks! – Xhantar Jan 11 '13 at 13:41

To remove everything before and after the brackets :

$ echo '[123]' | sed 's/.*\[//;s/\].*//;'

If your data is like this always meaning starting and ending with square brackets:

$ echo '[123]' | sed 's/.//;s/.$//;'
share|improve this answer
The data I'm working with will always start and end with a square bracket yes. I'd still like to know why my solution wasn't working though. Any ideas? And is there a way to do this without specifying 2x regex's? – Xhantar Jan 11 '13 at 10:49

If you have a more complex string like 'abcdef[123]ghijk' you can also use internal bash command 'cut' to extract text only between square brackets:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
share|improve this answer

You can escape the opening bracket using \[. For the closing bracket, use []].

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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