1

Is there a simpler way to replace a string with a variable literally that contains all complex characters without needing to do character escaping?

complex='~`!@#$%^&*()-_=+\|]}{[;:/?.>,<\/*&\#/'
sed -i "s/secret\ =\ \".*/secret\ =\ \"$complex\"/g" ./file.txt

I already know that & \ and / are the problems. I can do all manner of cleaning with sed commands, but is there a simpler way? Is there a way I can literally make sed read that variable as is?

My work around for now is the following, but even this does not work with / properly ...

complex='~`!@#$%^&*()-_=+\|]}{[;:/?.>,<\/*&\#/'
psk_bs="$(echo $complex | sed 's/\\/\\\\\\/g')"
psk_bs_amp="$(echo "$psk_bs" | sed 's/\&/\\&/g')"
psk_bs_amp_fs="$(echo "$psk_bs_amp" | sed 's,'/','\/',g')"
sed -i "s/secret\ =\ \".*/secret\ =\ \"$psk_bs_amp_fs\"/g" ./file.txt
Dave
  • 727
  • 1
  • 9
  • 20
  • How much do you care about using sed specifically, and not any other tool? [BashFAQ #21](https://mywiki.wooledge.org/BashFAQ/021) shows how you to do literal replace operations with either awk (see `gsub_literal` defined at the end) or perl (see the "Just Tell Me What To Do" section). – Charles Duffy Nov 09 '22 at 05:45

1 Answers1

1

I can do all manner of cleaning with sed commands, but is there a simpler way? Is there a way I can literally make sed read that variable as is?

I'm afraid there is not. But character escaping is not as a big deal as you make it seem to be. This'll work just fine:

psk=$(sed 's/[/&\]/\\&/g' <<< $complex)
sed -i "s/secret = \".*/secret = \"$psk\"/g" ./file.txt

With bash 5.2 you don't even need sed for escaping:

psk=${complex//[\/&\\]/\\&}
oguz ismail
  • 1
  • 16
  • 47
  • 69