Skip to content
Advertisement

How do I replace a string at an undetermined location in a .txt file with a Shell script?

I’m writing a Shell script using Bash to convert a Robot Framework resource file from Windows to Linux. The contents of the Resource file itself are not important, but here is the required “minimal, complete, and verifiable example”. beep is a typeless empty file used to test a site’s ability to upload files.

*** Variables ***
${DEFAULT_FILE}     C:\Users\user01\Desktop\beep

There will be an unspecified and ever-changing number of declared variables before and after that variable, so hard-coding the location won’t work.

I’d like to change this file, with a Shell script, to the following:

*** Variables ***
${DEFAULT_FILE}     //home//user01//Desktop//beep

The literals involved are driving me up one wall and down the other, and the errors are similarly driving me nuts. I’ve tried using sed, but the syntax recommendations from Stack Overflow are all over the place.

Here’s the most recent version of my code:

old="C:\\Users\\user01\\Desktop\\beep"
new="//home//user01//Desktop//beep"
sed -i 's|'"${old}"'|'"${new}"'' /home/user01/Desktop/test.txt

With my limited Bash experience, I’m sure it’s something simple, but for the life of me I can’t figure it out. The most recent errors I’m getting follow the pattern sed: -e expression #1, char [some number here]: unterminated 's' command. The value of the number changes every time.

Advertisement

Answer

You have to close pattern s/foo/bar/ – third / is missing.

Please try

sed -i 's|'"${old}"'|'"${new}"'|' /home/user01/Desktop/test.txt

Now sed runs but does not substitute

$ old="C:\\Users\\user01\\Desktop\\beep"
$ new="//home//user01//Desktop//beep"
$ cat > /tmp/foo
*** Variables ***
${DEFAULT_FILE}     C:\Users\user01\Desktop\beep
$ sed 's|'"${old}"'|'"${new}"'|' /tmp/foo
*** Variables ***
${DEFAULT_FILE}     C:\Users\user01\Desktop\beep

Need to escape one more time

$ old="C:\\\\Users\\\\user01\\\\Desktop\\\\beep"
$ sed 's|'"${old}"'|'"${new}"'|' /tmp/foo
*** Variables ***
${DEFAULT_FILE}     //home//user01//Desktop//beep

Ok, what’s going on?

Backslash is a special character in sh:

$ echo "
"

This gives us

$ old="C:\\Users\\user01\\Desktop\\beep"
$ echo 's|'"${old}"'|'"${new}"'|'
s|C:\Users\user01\Desktop\beep|//home//user01//Desktop//beep|

But backslash also special character in sed:

$ echo '+' | sed 's/+/-/'
-

So it searches for C:Usersuser01Desktopbeep which is not present in the sample file

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement