Updating a file with sed
Solution 1
I cant get something in sed. So i have used awk. Pass the Replace1 and Replace2 as argument to the shell script which will create the ip.sql with proper values.
#!/bin/bash
awk -v R1=$1 -v R2=$2 '{gsub("wordToFind1",R1);gsub("wordToFind2",R2);print}' ip.sql > t.sql;
mv t.sql ip.sql;
Solution 2
You have some problems to solve here.
Using slashes (/
) inside s///
First, you want to replace wordToFind1
with /usr/bin/try.txt
. It will not work with the s///
command at first, because the replacing string contains /
. It would to a very weird command!
sed -e 's/wordToFind1//usr/bin/try.txt/' Check.sql
Sed will think that the command is s/wordToFind1//
with some flags (such as u
) and other commands following, but it makes no sense and it will generate an error. A solution is to escape each /
from /usr/bin/try.txt
with \
:
$ sed -e 's/wordToFind1/\/usr\/bin\/try.txt/' Check.sql
servermonitor on
spool /usr/bin/try.txt
select * from wordToFind2
This is clumsy, however. When you have a lot of /
in your replacing string (or even in the replaced string), a better solution IMHO is to use another character as the delimiters of s///
. Not everybody knows it is possible, but one can use any other char instead of /
as the delimiter of s///
. In this case, you can use as much /
as you want inside your expressions without needing of escaping them. In the example below, I am using #
instead of /
, so the slashes from /usr/bin/try.txt
cause no trouble:
$ sed -e 's#wordToFind1#/usr/bin/try.txt#' Check.sql
servermonitor on
spool /usr/bin/try.txt
select * from wordToFind2
Using more than one s///
command
Solved that, you should replace wordToFind2
too. This is easy: just pass another -e
command in the same sed invocation:
$ sed -e 's#wordToFind1#/usr/bin/try.txt#' -e 's/wordToFind2/tablename/' Check.sql
servermonitor on
spool /usr/bin/try.txt
select * from tablename
(Another option is to add more than one option in one string only, separarated by semicolons:
$ sed -e 's#wordToFind1#/usr/bin/try.txt#;s/wordToFind2/tablename/' Check.sql
servermonitor on
spool /usr/bin/try.txt
select * from tablename
I find it very useful sometimes, with bigger sed scripts, but it is less readable as well).
Updating the input file with -i
Now, you need to update the Check.sql
file. This is easy as well: just pass the -i
flag to sed. This flag makes sed update the original file. Also, this flag can receive a parameter, that is an extension to be added to a backup file with the original content. In this case, I will use the .bkp
extension. See the results:
$ sed -i.bkp -e 's#wordToFind1#/usr/bin/try.txt#' -e 's/wordToFind2/tablename/' Check.sql
$ cat Check.sql
servermonitor on
spool /usr/bin/try.txt
select * from tablename
Now, Check.sql
changed. Also, there is a Check.sql.bkp
with the old content:
$ cat Check.sql.bkp
servermonitor on
spool wordToFind1
select * from wordToFind2
This may be helpful if something goes wrong.
Kannan Lg
Updated on June 04, 2022Comments
-
Kannan Lg almost 2 years
I am trying to find and replace a couple of words in a file and try to execute that file as a .sql file
sed -e "s/wordToFind1/UnixFile/g" Check.sql; sed -e "s/wordToFind2/WordToReplace2/g" Check.sql;
In the above, I am trying to find wordToFind1 and replace it with a UnixFile : /usr/bin/try.txt and then, trying to find wordToFind2 and replace it with another word : tablename
Before sed - Check.sql :
servermonitor on spool wordToFind1 select * from wordToFind2
After sed - Check.sql :
servermonitor on spool /usr/bin/try.txt select * from tablename
Once the above changes are done, I am trying to execute the sql file. Please help!!!