1

I've created a bash script that gets an IP Address as variable ${MYSQL_SERVER_IP}. I then want to pass it in a sed to replace the previous IP address in a settings.py file. Here is the closest I have gotten to a sed statement that actually runs without error:

export MYSQL_SERVER_IP= '172.19.0.2'
sed -i -e '/DB_HOST =/c\DB_HOST = os.getenv( '\''IP'\'', '\''${MYSQL_SERVER_IP}'\'')\' Flask-URL-Shortener/settings.py

The problem is that the script doesn't replace the variable with the value of the variable.

In the file before running the script:

DB_HOST = os.getenv( 'IP', '172.31.0.2')

Currently the output I get is wrong:

DB_HOST = os.getenv( 'IP', '${MYSQL_SERVER_IP}')

as I would like to obtain the following output:

DB_HOST = os.getenv( 'IP', '172.19.0.2')

This sed statement is the last line of code I need to fix to make my program work the way I want it to.

6
  • I see that you have included in your question the current output and the desired output; can you please also include in the question the corresponding input? Commented Dec 14, 2019 at 20:47
  • 1
    The pattern /\DB_HOST =\**/ matches DB_HOST = followed by zero or more *; is this your intention? (By the way it works just because \D is not special, so `` is actually ineffective.) Commented Dec 14, 2019 at 21:00
  • @oguzismail When I try quoting my variable, it just puts the quotes in the setting.py file, no matter what I do, it does not replace the variable with the value of the variable Commented Dec 14, 2019 at 21:01
  • Please, provide an example, few lines input file. Commented Dec 14, 2019 at 21:02
  • 1
    My understanding is that DB_HOST = os.getenv( 'IP', '${MYSQL_SERVER_IP}') is what you currently get upon using your broken command (because you wrote Current replacement), and that DB_HOST = os.getenv( 'IP', '172.19.0.2') is what you want to get (because you wrote Desired). @WilliamPursell, in his answer, assumes that DB_HOST = os.getenv( 'IP', '${MYSQL_SERVER_IP}') is what you have in your settings.py file before editing it. Can you please clarify this? Besides, as I already wrote in a comment, please stop writing code in the comments and edit your question. Commented Dec 14, 2019 at 21:46

2 Answers 2

2

Based on your comment, it seems like you need the following command

sed '/DB_HOST/s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/'"$MYSQL_SERVER_IP"'/' yourfile

where the substitution command s is applied only to the lines matching the DB_HOST pattern (you can make it more complicated, e.g. /DB_HOST *= */, to match DB_HOST followed by =, the latter preceded and followed by zero or more spaces); the regexp of the s command contains 4 expressions matching between 1 and 3 digits ([0-9]\{1,3\}), interspersed with literal dots \..

Original answer

Please, if the next three lines do not describe your case, leave a comment and clarify.

Let's say myShortFile contains only this line (since it is a simple text file, all characters, $ included, are literal):

IP = $MYIP

Then, if you run such a bash script:

#!/bin/bash
MYIP="172.19.0.2"
sed 's/$MYIP/'"$MYIP"'/' myShortFile

you will get

IP = 172.19.0.2

The reason is that in the string concatenation '…'"…"'…', the first and the third parts ('s/$MYIP/' and /) are interpreted literally by bash, since they are enclosed in single quotes ('), whereas the $MYSIP in the middle piece "$MYIP" is expanded, since it is in between double quotes ("). The result is that bash will execute the command

sed 's/$MYIP/172.19.0.2/' myShortFile

which substitutes $MYIP in myShortFile with 172.19.0.2 and prints the resulting output to screen.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks, but the file does not have any variables. I added how the file looks before running. The IP address in the file and in the variable are going to be different every run
2

I don't think you want to be using c here. Just do:

sed -e '/DB_HOST\s*=/s/${MYSQL_SERVER_IP}/'"${MYSQL_SERVER_IP}"/

You can limit the replacement to the line containig DB_HOST =, but you don't need to try to do anything with that text in the replacement. Only replace the part that needs to be changed. Note that this will fail if MYSQL_SERVER_IP contains forward slashes, so you'll want to validate the data.

2 Comments

Thanks, I tried: sed -i -e '/DB_HOST\s*=/s/${MYSQL_SERVER_IP}/'"${MYSQL_SERVER_IP}"/ Flask-URL-Shortener/settings.py but I got back this: sed: -e expression #1, char 75: unterminated `s' command . Which is weird since char 75 is where the file is in the command
I also tried: sed -i -e '/DB_HOST\s*=/s/${MYSQL_SERVER_IP}/"${MYSQL_SERVER_IP}"/' Flask-URL-Shortener/settings.py but all it does is replace "${MYSQL_SERVER_IP}" with ""${MYSQL_SERVER_IP}"" (with more double quotes). Also the file is not going to have ${MYSQL_SERVER_IP} inside of it. It's going to have an actual IP Address to replace

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.