简体   繁体   English

SED 语句替换 Shell 脚本中的变量

[英]SED statement to replace variable inside Shell Script

I've created a bash script that gets an IP Address as variable ${MYSQL_SERVER_IP} .我创建了一个 bash 脚本,它获取一个 IP 地址作为变量${MYSQL_SERVER_IP} I then want to pass it in a sed to replace the previous IP address in a settings.py file.然后我想在 sed 中传递它以替换 settings.py 文件中以前的 IP 地址。 Here is the closest I have gotten to a sed statement that actually runs without error:这是我最接近实际运行没有错误的 sed 语句:

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.这个 sed 语句是我需要修复的最后一行代码,以使我的程序按照我想要的方式工作。

I don't think you want to be using c here.我不认为你想在这里使用c 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.您可以将替换限制为包含DB_HOST =的行,但您无需尝试在替换中对该文本执行任何操作。 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.请注意,如果 MYSQL_SERVER_IP 包含正斜杠,这将失败,因此您需要验证数据。

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, eg /DB_HOST *= */ , to match DB_HOST followed by = , the latter preceded and followed by zero or more spaces);其中替换命令s仅应用于匹配DB_HOST模式的行(您可以使其更复杂,例如/DB_HOST *= */ ,以匹配DB_HOST后跟= ,后者前后跟零个或多个空格); the regexp of the s command contains 4 expressions matching between 1 and 3 digits ( [0-9]\\{1,3\\} ), interspersed with literal dots \\. s命令的正则表达式包含 4 个匹配 1 到 3 位数字 ( [0-9]\\{1,3\\} ) 的表达式,中间穿插着文字点\\. . .

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):假设myShortFile只包含这一行(因为它是一个简单的文本文件,所有字符,包括$ ,都是文字):

IP = $MYIP

Then, if you run such a bash script:然后,如果您运行这样的bash脚本:

#!/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原因是在字符串连接'…'"…"'…' ,第一和第三部分( 's/$MYIP/'/ )被bash逐字解释,因为它们被括在单引号( ' ),而$MYSIP中间一块"$MYIP"展开,因为它是在双引号(间" ),其结果是, bash将执行命令

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.其中替代$MYIPmyShortFile172.19.0.2 ,并打印输出结果屏幕。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM