Replacing special characters in a shell script using sed

Solution 1:

I suggest two improvements:

  1. Do not stack calls to sed as you do, instead pack all of them in a single function, as escape_string below.

  2. You can use a fancy delimiter for the sed substitute command to avoid issues linked to / being part of the strings involved.

With these changes, your script looks like:

#! /bin/sh
oldString="$1"
newString="$2"
file="$3"

escape_string()
{
   printf '%s' "$1" | sed -e 's/[][\\^*+.$-]/\\\1/g'
}

fancyDelim=$(printf '\001')

oldStringFixed=$(escape_string "$oldString")
sed -e "s$fancyDelim$oldStringFixed$fancyDelim$newString${fancyDelim}g" "$file" \
  > newfile.updated
mv newfile.updated "$file"

Solution 2:

Change:

oldStringFixed= `sed 's/\[/\[/g' "$oldString"\`

to:

oldStringFixed=$(echo "$oldString" | sed 's/\[/\\\[/g')

Problem 1: Space after =, it's not allowed when assigning shell variables.

Problem 2: sed expects a file as input, not a string. You may pipe it as my solution does though.

Problem 3: You need to escape the backslash first \\, then you need to escape your char \[, totalling \\\[ :)

Side note: I changed `` to $() since the latter is the recommended praxis (due to nesting, another topic).

Solution 3:

To replace values containing special characters try using sed with "|" instead of "/"

Eg: sed -i 's|'$original_value'|'$new_value'|g'

where original_value="comprising_special_char_/" new_value="comprising_new_special_char:"