使用sh文件查找并替换



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

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

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');

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')"
# ---------------------^  --------------^

编辑

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

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

如果第一个字符不是'/',有些种子'坚持'要转义,所以如果只是普通的s#...#...#g' doesn't work, try s#…#…(只是第一次提到#)。如果在目标字符串或repl字符串中有"#"字符,则必须使用不同的分隔符。

如果您使用shell调试模式,即set -vx(插入在脚本顶部附近),它将有所帮助。然后,您将看到每一行被执行的代码,并将变量扩展到它们所赋的值。

我希望这对你有帮助。

注:由于您看起来是一个新用户,如果您得到一个对您有帮助的答案,请记住将其标记为接受,并/或给它一个+(或-)作为一个有用的答案。

sudo sed -i s+$REPLACESTRING10+$REPLACESTRING12+g ...

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

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

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

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

此外,进行就地编辑似乎有点冒险。也许你应该有一个"源"文件,你修改和安装到不同的目的地与任何修改你需要?

最新更新