I'm trying to replace a string in database. I found the possible solutions below. Using # or % works to me, but not for / and |. Can anyone explain why the first two works and what the differences are between them please? find . -type f -name 'file.sql' -exec sed -i '' s#http://a.com#http://b.com#g {} +find . -type f -name 'file.sql' -exec sed -i '' s%http://a.com%http://b.com%g {} +find . -type f -name 'file.sql' -exec sed -i '' s/http://a.com/http://b.com/g {} +find . -type f -name 'file.sql' -exec sed -i '' s|http://a.com|http://b.com|g {} +
The differences between sed #, %, / and |
sed;find;exec
Sed's substitution command typically uses / as the delimiter between the s command, the search string, the replacement string, and any flags. If, however, either of the search string or replacement string may contain a /, then people will change the delimiter to a character that is not in either of the strings.You received the other error from sed when you told it to use an empty string as the backup extension; since you're not using an extension, don't put the empty quotes in.Sed does not care what the delimiter is, but your surrounding shell might.The | symbol introduces a pipe. To use it as a delimiter, you would have to quote it in some fashion to protect them from the shell. The # symbol may introduce a comment string, based on your shell (bash only begins a comment if the # is the first character of a word), so better to be safe and quote it.Since your data contains / characters, you either need to use a different delimiter, or escape every instance of / in the search and replacement strings. This leads to what's known as leaning toothpick syndrome because of the hard-to-read appearance of the \/.Thus, you'd need something like:find . -type f -name 'file.sql' -exec sed -i -e 's#http://a.com#http://b.com#g' {} +orfind . -type f -name 'file.sql' -exec sed -i -e 's|http://a.com|http://b.com|g' {} +orfind . -type f -name 'file.sql' -exec sed -i -e s|http://a.com|http://b.com|g {} +orfind . -type f -name 'file.sql' -exec sed -i -e 's/http:\/\/a.com/http:\/\/b.com/g' {} +