1

I'm using the Git Bash shell on Windows, and trying to replace a string like this in an XML file using sed:

<customTag>C:\path\to\2016a.0</customTag> 

To a string like this:

<customTag>C:\path\to\2017b.0</customTag> 

I can do the replacement directly like this:

$ cat test.txt <customTag>C:\path\to\2016a.0</customTag> $ sed -i 's^<customTag>C:\\path\\to\\2016a.0</customTag>^<customTag>C:\\path\\to\\2017b.0</customTag>^g' test.txt $ cat test.txt <customTag>C:\path\to\2017b.0</customTag> 

But if I need to pass in variables for those strings, the replacement doesn't work.

$ cat test.txt <customTag>C:\path\to\2016a.0</customTag> $ export OLD_VER=2016a.0 $ export NEW_VER=2017b.0 $ sed -i 's^<customTag>C:\\path\\to\\${OLD_VER}</customTag>^<customTag>C:\\path\\to\\${NEW_VER}</customTag>^g' test.txt $ cat test.txt <customTag>C:\path\to\2016a.0</customTag> 

Or if I use double quotes around the sed expression, I get "Invalid back reference", presumably because it thinks the 2 in the year is a reference.

$ sed -i "s^<customTag>C:\\path\\to\\${OLD_VER}</customTag>^<customTag>C:\\path\\to\\${NEW_VER}</customTag>^g" test.txt sed: -e expression #1, char 87: Invalid back reference 

What's the correct way to escape or quote this, or would I be better off using something like awk?

2
  • Awesome! Yes, it works with the single quotes at the ends and with single quotes around the variable names. I didn't think the variables would get translated if they had single quotes, but taken as literal string values. Commented May 3, 2017 at 16:01
  • By adding single quotes, you're ending the quoted string before the variable and start it again after. You should actually double quote the variable to avoid word splitting: 's/xxx'"$var1"'/yyy'"$var2"'/' Commented May 3, 2017 at 16:28

1 Answer 1

2

Keep the single quotes on the ends, and add single quotes around each variable. The single quotes prevent the shell from collapsing your double backslashes. The extra single quotes leave the variable refs outside of quotes.

Or (don't laugh) consider using forward slashes. Windows recognizes both kinds of slash as path separators; it's only the DOS command shell that does not.

Sign up to request clarification or add additional context in comments.

1 Comment

Yep, Mischa beat me to it. I have the same answer. Try this: sed -i 's^<customTag>C:\\path\\to\\'${OLD_VER}'</customTag>^<customTag>C:\\path\\to\\'${NEW_VER}'</customTag>^g' test.txt

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.