Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to extract a substring from a string with sed on cygwin.

#!/bin/bash

var1="foo\ bar"
var2="baz"

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

3 Answers 3

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:

#!/bin/bash
export var1="foo\ bar" ## The export allows Perl to access the variable as $ENV{var1}
var2="baz"
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 ....like 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//\\/\\\\}//"
 baz

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

 
discard

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.