使用 sh 文件查找和替换

发布于 2024-11-28 12:21:24 字数 3265 浏览 2 评论 0原文

我正在编写一个自动备份和镜像脚本,该脚本或多或少会复制文件、数据库、设置权限,并稍微修改镜像文件,以便它们在具有备份文件的另一台服务器上工作。我已经编写并设置了除重新配置之外的所有内容。我所有的尝试都失败了,我不知道如何解决它。

所以这些是相关行(修改为公共使用):

FOLDER="kf.hammertime.com.au"
SERVER="fulcan"
BACKUPUSER="backupclient3"
DESTINATION="/var/www/Backup-Server"
SOURCE="/var/www"

RECONFIG="1"

if [ "${RECONFIG}" = "1" ]
then
#Original to be replace
echo Reconfiguring website for the mirrored site.
REPLACESTRING10="define (\'ROOT_PATH\', \'\/var\/www\/${FOLDER}\/trunk\')"
REPLACESTRING20="define ('DB_PASSWORD', 'hammertime1')"
REPLACESTRING30="define ('DB_USERNAME', 'hammertime2')"
REPLACESTRING40="define ('DB_HOST', 'localhost')"

#String to be replaced
REPLACESTRING11="define ('ROOT_PATH', '${SOURCE}\/${FOLDER}')"
REPLACESTRING21="define ('DB_PASSWORD', 'hammertime3')"
REPLACESTRING31="define ('DB_USERNAME', 'hammertime4')"
REPLACESTRING41="define ('DB_HOST', 'hammertime5')"

REPLACESTRING12="define (\'ROOT_PATH\', \'${SOURCE}\/${FOLDER}\/trunk\')"

echo ${REPLACESTRING10}

#Reconfigure various configuration files for Backup-Server active use

#find /your/home/dir -name "*.txt" | xargs perl -pi -e 's/stringtoreplace/replacementstring/g'

#Edits the files regardless if its in trunk or not. Will come up with errors.

#sudo replace "${REPLACESTRING10}" "${REPLACESTRING12}" <${DESTINATION}/${FOLDER}/trunk/lib/config.php> ${DESTINATION}/${FOLDER}/trunk/lib/config2.php

#sudo sed -i s/"${REPLACESTRING10}"/"${REPLACESTRING12}"/g  ${DESTINATION}/${FOLDER}/trunk/lib/config.php

#sudo perl -i -p -e 's{${REPLACESTRING10}}{${REPLACESTRING12}}g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php


sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING12}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php

#sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING11}/g' ${DESTINATION}/${FOLDER}/lib/config.php

#sudo sed -i 's/${REPLACESTRING20}/${REPLACESTRING21}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php
#sudo sed -i 's/${REPLACESTRING20}/${REPLACESTRING21}/g' ${DESTINATION}/${FOLDER}/lib/config.php

#sudo sed -i 's/${REPLACESTRING30}/${REPLACESTRING31}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php
#sudo sed -i 's/${REPLACESTRING30}/${REPLACESTRING31}/g' ${DESTINATION}/${FOLDER}/lib/config.php

#sudo sed -i 's/${REPLACESTRING40}/${REPLACESTRING41}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php
#sudo sed -i 's/${REPLACESTRING40}/${REPLACESTRING41}/g' ${DESTINATION}/${FOLDER}/lib/config.php
fi

简而言之,行“sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING12}/g' ${DESTINATION}/${FOLDER}/trunk/ lib/config.php" 根本不能很好地接受变量。

所以我尝试使用 perl 替代方案但无济于事(但我本来可以不使用它)。我的大部分尝试都列在那里。以及更换。

我只需要更改单个文件中的某些行(行编号可以更改)。

预先感谢您的时间和耐心(顺便说一句,这是第一次编写 SH 脚本,我习惯了 BAT,所以我确信我已经掌握了其中的大部分内容,但它与没有错误)

编辑: 文件块看起来像:

define ('ROOT_PATH', '/var/www/kf.hammertime.com.au/trunk');
define ('DB_HOST', 'hammertime1');
define ('DB_USERNAME', 'hammertime2');
define ('DB_PASSWORD', 'localhost');

我想将其更改为:

define ('ROOT_PATH', '/var/www/Backup-Server/kf.hammertime.com.au/trunk');
define ('DB_HOST', 'hammertime3');
define ('DB_USERNAME', 'hammertime4');
define ('DB_PASSWORD', 'hammertime5');

但其中一些编辑的项目将是变量......

Im writting up an automated backup and mirroring script which will more or less, copy over the files, the db, setup permissions, and modify the mirrored files slightly so they work on the other server with the backed up file. I've written and set everything else up except the reconfig. All my attempts have failed and I don't know how to get around it.

So these are the relevent lines(modified for public use):

FOLDER="kf.hammertime.com.au"
SERVER="fulcan"
BACKUPUSER="backupclient3"
DESTINATION="/var/www/Backup-Server"
SOURCE="/var/www"

RECONFIG="1"

if [ "${RECONFIG}" = "1" ]
then
#Original to be replace
echo Reconfiguring website for the mirrored site.
REPLACESTRING10="define (\'ROOT_PATH\', \'\/var\/www\/${FOLDER}\/trunk\')"
REPLACESTRING20="define ('DB_PASSWORD', 'hammertime1')"
REPLACESTRING30="define ('DB_USERNAME', 'hammertime2')"
REPLACESTRING40="define ('DB_HOST', 'localhost')"

#String to be replaced
REPLACESTRING11="define ('ROOT_PATH', '${SOURCE}\/${FOLDER}')"
REPLACESTRING21="define ('DB_PASSWORD', 'hammertime3')"
REPLACESTRING31="define ('DB_USERNAME', 'hammertime4')"
REPLACESTRING41="define ('DB_HOST', 'hammertime5')"

REPLACESTRING12="define (\'ROOT_PATH\', \'${SOURCE}\/${FOLDER}\/trunk\')"

echo ${REPLACESTRING10}

#Reconfigure various configuration files for Backup-Server active use

#find /your/home/dir -name "*.txt" | xargs perl -pi -e 's/stringtoreplace/replacementstring/g'

#Edits the files regardless if its in trunk or not. Will come up with errors.

#sudo replace "${REPLACESTRING10}" "${REPLACESTRING12}" <${DESTINATION}/${FOLDER}/trunk/lib/config.php> ${DESTINATION}/${FOLDER}/trunk/lib/config2.php

#sudo sed -i s/"${REPLACESTRING10}"/"${REPLACESTRING12}"/g  ${DESTINATION}/${FOLDER}/trunk/lib/config.php

#sudo perl -i -p -e 's{${REPLACESTRING10}}{${REPLACESTRING12}}g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php


sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING12}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php

#sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING11}/g' ${DESTINATION}/${FOLDER}/lib/config.php

#sudo sed -i 's/${REPLACESTRING20}/${REPLACESTRING21}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php
#sudo sed -i 's/${REPLACESTRING20}/${REPLACESTRING21}/g' ${DESTINATION}/${FOLDER}/lib/config.php

#sudo sed -i 's/${REPLACESTRING30}/${REPLACESTRING31}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php
#sudo sed -i 's/${REPLACESTRING30}/${REPLACESTRING31}/g' ${DESTINATION}/${FOLDER}/lib/config.php

#sudo sed -i 's/${REPLACESTRING40}/${REPLACESTRING41}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php
#sudo sed -i 's/${REPLACESTRING40}/${REPLACESTRING41}/g' ${DESTINATION}/${FOLDER}/lib/config.php
fi

So in short the line "sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING12}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php" doesn't take in variables very well at all.

So ive tried using the perl alternative but to no avail (but i could have been n00bing it). Most of my attempts are listed there. As well as replace.

I just need to change certain lines (the line numbering can change) in a single file.

Thanks in advance for your time and Patience (By the way, this is the first time writing an SH script, I'm used to BAT, so I'm sure I've n00bed a fair chunk of it, but it works well with no errors)

EDIT:
The file chunk looks like:

define ('ROOT_PATH', '/var/www/kf.hammertime.com.au/trunk');
define ('DB_HOST', 'hammertime1');
define ('DB_USERNAME', 'hammertime2');
define ('DB_PASSWORD', 'localhost');

And i want to change it to:

define ('ROOT_PATH', '/var/www/Backup-Server/kf.hammertime.com.au/trunk');
define ('DB_HOST', 'hammertime3');
define ('DB_USERNAME', 'hammertime4');
define ('DB_PASSWORD', 'hammertime5');

But some of these edited items will be variables...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蘑菇王子 2024-12-05 12:21:24

sed 字符串内的变量替换必须用双引号引起来。即,您已

 sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING12}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php

替换为

 sudo sed -i "s/${REPLACESTRING10}/${REPLACESTRING12}/g" ${DESTINATION}/${FOLDER}/trunk/lib/config.php

“修复此问题”,然后告诉我们下一个问题是什么。您可能需要转义 REPLACESTRINGn 中嵌入的任何空格或制表符,例如

REPLACESTRING20="define\ ('DB_PASSWORD',\ 'hammertime1')"
# ---------------------^  --------------^

Edit

当然,所有 sed 问题的杀手是搜索字符串或替换字符串中嵌入的“/” 。大多数 sed 允许使用除 '/' 之外的其他字符,因此请尝试

 sudo sed -i "s#${REPLACESTRING10}#${REPLACESTRING12}#g" ${DESTINATION}/${FOLDER}/trunk/lib/config.php

一些 sed '坚持',如果第一个字符不是 '/',则转义它,所以如果只是简单的 s#...#...# g' 不起作用,请尝试 s\#...#...`(只是第一次提到 #)。如果你的目标或 repl 字符串中有“#”字符,那么你必须找到一个不同的分隔符来使用。

如果您使用 shell 调试模式,即 set -vx (在脚本顶部附近插入),将会有所帮助。然后,您将看到执行时的每一行,其中变量扩展为其分配的值。

我希望这有帮助。

PS,由于您似乎是新用户,如果您得到的答案对您有帮助,请记住将其标记为已接受,和/或给它 +(或 -)作为有用的答案。

Variable replacement inside of sed strings must be in double quotes. i.e., you have

 sudo sed -i 's/${REPLACESTRING10}/${REPLACESTRING12}/g' ${DESTINATION}/${FOLDER}/trunk/lib/config.php

replace with

 sudo sed -i "s/${REPLACESTRING10}/${REPLACESTRING12}/g" ${DESTINATION}/${FOLDER}/trunk/lib/config.php

Fix this and then tell us what the next problem is. You may need to escape any space or tab chars embedded in the REPLACESTRINGn like

REPLACESTRING20="define\ ('DB_PASSWORD',\ 'hammertime1')"
# ---------------------^  --------------^

Edit

And of course, the killer of all sed issues, is the embedded '/' in the either the search string or the replacment string. Most seds allow using other characters besides the '/', so try

 sudo sed -i "s#${REPLACESTRING10}#${REPLACESTRING12}#g" ${DESTINATION}/${FOLDER}/trunk/lib/config.php

Some seds 'insist' that you escape the first char if it is not '/', so if just plain s#...#...#g' doesn't work, trys\#...#...` (just the first mention of #). AND if you have '#' chars in either your target or repl string, then you'll have to find a different delimiter to use.

It will help if you use the shell debugging mode, i.e. set -vx (insert near top of script). Then you'll see each line as it is executed with the variables expanded to their assigned values.

I hope this helps.

P.S. as you appear to be a new user, if you get an answer that helps you please remember to mark it as accepted, and/or give it a + (or -) as a useful answer.

笔落惊风雨 2024-12-05 12:21:24
sudo sed -i s+$REPLACESTRING10+$REPLACESTRING12+g ...
sudo sed -i s+$REPLACESTRING10+$REPLACESTRING12+g ...
情感失落者 2024-12-05 12:21:24

单引号防止替换,您需要使用双引号。但更重要的是,您需要将源字符串更改为正则表达式,因为这是 sedperl (以及其他类似工具)所理解的。

Perl 实际上可以为您将文字字符串更改为正则表达式,如下所示:

perl -pi -e 'BEGIN { $src = quotemeta(shift @ARGV); }
    s/$src/'"${REPLACESTRING12}/g" "$REPLACESTRING10" file

多个替换可能都应该由单个脚本完成,无论是 sedperl 还是其他脚本别的。 (显然,每个目标文件一个。)这也应该有助于使脚本更具可读性。

此外,进行就地编辑似乎有点冒险。也许您应该拥有一个“源”文件,您可以根据需要进行修改并安装到各个目的地?

The single quotes prevent substitution, you need to use double quotes. But what's more, you need to change the source string into a regular expression, because that's what sed and perl (and other similar tools) understand.

Perl can actually change a literal string into a regex for you, like this:

perl -pi -e 'BEGIN { $src = quotemeta(shift @ARGV); }
    s/$src/'"${REPLACESTRING12}/g" "$REPLACESTRING10" file

The multiple replacements should probably all be done by a single scripts, be it sed or perl or something else. (One per destination file, obviously.) This should help make the script more readable, too.

Moreover, making in-place edits seems a bit risky. Perhaps you should have one "source" file which you modify and install to various destinations with whatever modifications you need?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文