0

I'm trying to replace a string in a file. i have to use a variable since i have to do this in alot of lines. how do i escape the backslash?

text.txt:

1234567#Hello World#Hello I\u0027m Scott

script:

#!/bin/bash
FOLDERID=`cat text.txt | cut -d# -f1`  # example: 12345
oldstring=`cat text.txt | cut -d# -f2` # example: "Hello World"
newstring=`cat text.txt | cut -d# -f3` # example: "Hello I\u0027m Scott"
sed -i "s/${oldstring}/${newstring}/g" $FOLDERID/myfile.txt

cat myfile.txt after sed

Hello I0027m Scott

how can i escape a backslash? i only know how to escape slashes which would work like:

newstring=Hello I/u0027m Scott
newstring=${newstring//\//\\\/}
echo ${newstring} # => Hello I\/u0027m Scott
  • can you add a clearer example? preferably in this order: 1) contents of `myfile.txt` before modification 2) content of `external file` 3) variable containing string to replace 4) expected output of `myfile.txt` after change – Sundeep Oct 27 '16 at 12:54
  • myfile.txt contains text + the oldstring – professorswag123 Oct 27 '16 at 13:06
  • Just to clarify, is the `\u0027` the six characters ```\``` `u` `0` `0` `2` `7`, or is it the Unicode character with hex value `0x27` (i.e., `'`)? I presume the former, but want to check just in case. **Also**, see [this question](https://stackoverflow.com/q/29613304/2877364). – cxw Oct 27 '16 at 13:09
  • yes it's unicode ' but i have to write it like this – professorswag123 Oct 27 '16 at 13:11
  • six bytes in text.txt – professorswag123 Oct 27 '16 at 13:13

2 Answers2

2

Try this:

cd /tmp
mkdir -p 1234567
echo Hello World >1234567/myfile.txt
echo '1234567#Hello World#Hello I\u0027m Scott' >text.txt

Well, then:

IFS=\# read -r FOLDERID oldstring newstring <text.txt 
sed "s/${oldstring}/${newstring//\\/\\\\}/g" -i $FOLDERID/myfile.txt
cat 1234567/myfile.txt 
Hello I\u0027m Scott
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137
0

@F.Hauri's example worked for me, but in my case, the string on the left may have had backslashes, so I did this:

#!/bin/bash

source my.cfg -r # Read VAR from my.cfg

echo "Old variable is \"${VAR}\""
echo -n "Input   : "
read -r newvar
echo    "You said: \"${newvar}\""

sed -i -e "s/'${VAR//\\/\\\\}'/'${newvar//\\/\\\\}'/g" my.cfg

echo "my.cfg is now:"
echo
cat my.cfg

But I will confess, I do not completely understand

//\\/\\\\
  • So `${var//pattern/string}` is bash parameter substitution using regex. For that invocation of `$var`, it performs the `//` substitution, which is to find all occurrences of `pattern` in `string`. ... I had a great writeup here, but apparently StackOverflow's comment parsing messes up with too many backticks and backslashes. hahaha Put simply, you need to double-up backslashes since a single backslash indicates a regex entity. – Cliff Aug 22 '23 at 04:31