Find and replace using a sh file
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 number开发者_运维知识库ing 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...
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, try
s\#...#...` (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.
sudo sed -i s+$REPLACESTRING10+$REPLACESTRING12+g ...
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?
精彩评论