Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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 am trying to extract a substring from a string with sed on cygwin.


var1="foo\ bar"

var3="$var1 $var2"

# extract "foo\ bar" from "foo\ bar baz"
var4=`echo $var3 | sed "s/"$var1"//"`
echo "$var4"

but I get the following output, caused by the backslash: sed: -e expression #1, char 6: unterminated `s' command

how can I write the sed command to output 'baz'?

share|improve this question
up vote 2 down vote accepted

The problem is that both the shell and sed interpret backslashes. You may be able to get sed to do this properly, but I would recommend simply using a different tool, for example, Perl:

export var1="foo\ bar" ## The export allows Perl to access the variable as $ENV{var1}
var3="$var1 $var2"

# extract "foo\ bar" from "foo\ bar baz"
var4=`echo $var3 | perl -ne '$var1=quotemeta($ENV{var1}); s/$var1//; print'`
echo "$var4"

The above example uses Perl's quotemeta function which escapes all non-ASCII characters, enabling the regex to correctly match the backslash.

Finally, why do you want to do this? Do you really need to match the \ or are you trying to match spaces in bash strings? There are easier ways if so.

share|improve this answer
The perl script can be golfed a bit: perl -pe "s/\Q$var1//" – glenn jackman Jun 12 '13 at 20:55
@glennjackman nice! I take it the \Q is shorthand for quotemeta? I won't change the answer cause it's clearer as is but that's good to know, thanks. – terdon Jun 13 '13 at 1:26

to put it simply .... sed dosen't work on coloumns , its more row oriented approach. Dont force a command - use it where its suitable. Cut would be a better/simpler option

alternatively if the substring extraction is what you are looking for then awk is also suited for that ... example

Kaizen ~/so_test
$ echo "foo\ bar baz" | awk '{print substr($0,1,8)}'
+ echo 'foo\ bar baz'
+ awk '{print substr($0,1,8)}'
foo\ bar

its more simple to use in this case , does this suffice ?

share|improve this answer

To make this work with sed, we need to escape the backslashes. Get ready for madness:

$ echo "$var1"
foo\ bar
$ echo "$var3"
foo\ bar baz
$ echo "$var3" | sed "s/$var1//"
foo\ bar baz
$ echo "${var1//\\/\\\\}"
foo\\ bar
$ echo "$var3" | sed "s/${var1//\\/\\\\}//"

Of course, there are plenty of other characters that require escaping as well, such as *, so @terdon's perl answer is better than this toothpick forest.

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.