2

I have written a bash script which calls a sed command (amongst other things) on a file to complete a find/replace of 2 different strings.

The trouble is, after running the script, I check the files and nothing has been updated. However, if I run the commands that are being produced (I echo them as output anyway) then they work.

For example, inside the script I have:

echo "/usr/local/bin/sed -i -e 's/${String1}/${String1R}/g;s/\/${String2}\//\/${String2R}\//g' ${ROOT_DIR}/data/file.sql"
/usr/local/bin/sed -i -e 's/${String1}/${String1R}/g;s/\/${String2}\//\/${TString2R}\//g' ${ROOT_DIR}/data/file.sql

Running the script does not change file.sql; however, if I run the command that is printed to console e.g. /usr/local/bin/sed -i -e 's/file_name1/file_name2/g;s//path_substring1///path_substring2//g' /path/to/file/file.sql it works perfectly!

2
  • 1
    I don't get the purpose of the "echo"... Commented Nov 22, 2013 at 10:51
  • You use the word "string" a lot, but your script isn't doing string comparison, it's doing regexp comparison, is that OK? It will come back to bite you if "String1". for example, contains RE meta-characters such as ., ?, *, etc. Commented Nov 22, 2013 at 13:25

1 Answer 1

6

Use double quotes instead of single quotes. Single quotes would prevent variable expansion.

/usr/local/bin/sed -i -e "s/${String1}/${String1R}/g;s/\/${String2}\//\/${TString2R}\//g" ${ROOT_DIR}/data/file.sql

Moreover, it seems that your variables are path strings which might contain forward slashes, i.e. /. In that event use a different separator:

"s|${String1}|${String1R}|g"

Using a different separator would obviate the need of escaping / in the pattern and replacement.

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

4 Comments

Thanks devnull. One thing, substituting / with | didn't work. Luckily, the path substrings should not contain any slashes however, it would be cleaner without having to escape them. Do you need to provide the separator as a separate argument?
@user2294382 I'm not sure why it didn't work for you. As an example, try executing the command: echo a/b/c | sed "s|/b/|//d//|g" and observe what it does.
Hmm strange that worked - i get a//d//c. I must have done something wrong. Thanks
@user2294382 Yes, that is precisely what was the expected output. I was attempting to illustrate the fact that you didn't need to escape the / in the pattern and the replacement. The pattern /b/ was replaced by //d// without escaping the slash.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.