sed quotes and backslashes on cygwin

1

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'?

elSnape

Posted 2013-06-12T18:48:23.100

Reputation: 13

Answers

2

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.

terdon

Posted 2013-06-12T18:48:23.100

Reputation: 45 216

1The perl script can be golfed a bit: perl -pe "s/\Q$var1//" – glenn jackman – 2013-06-12T20:55:33.980

@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 – 2013-06-13T01:26:21.167

1

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 ?

nitin

Posted 2013-06-12T18:48:23.100

Reputation: 179

0

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.

glenn jackman

Posted 2013-06-12T18:48:23.100

Reputation: 18 546