Updating a file with sed

14,070

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.

Share:
14,070
Kannan Lg
Author by

Kannan Lg

Updated on June 04, 2022

Comments

  • Kannan Lg
    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!!!