Shell Script [Replacing string]

My friend and I are working on a project together and we are trying to create a shell script that renames, replaces a string in a text file. The newly created file with the substitution would replace the name of the original file. And the original file would be saved as "____.txt.bak"

This is the code we came up with:

#!/bin/sh

if [ -e "$3" ] ; then
mv "$3" "$3.bak"
sed "s/$1/$2/g" "$3.bak" > "$3"
else
echo $3 not found
exit 1
fi

To test it, we created a file called happy.txt and in that file, there are only four words: happy happy cow happy

we did: ~/test/subst1 cow happy happy.txt

We thought that this would replace cow with happy, but it didn't work, we got this in return as a message:

~/test/subst1: test: argument expected

Any help would be appreciated...

Try:

if [ -f "$3" ] ; then

Hey thanks for that, it worked :smiley:

but there's another problem now...we are trying now to create a second script called "subst2" that does the exact same thing as the "subst1" but leaves the file completely unchanged (and does not create the .bak file) if the string being replaced is nowhere in the file.

Also, the subst2 is supposed to be generalized so that it will produce a new script called "subst" that will apply a substitution to any amount of files...for example:

~/test/subst happy cow myFile1.txt myFile2.txt myFile3.txt

I figured that this might work:

#!/bin/sh

if [ -z "$3" ] ; then 
echo expect string1, string2, file
exit 1
fi 
if [ -e "$3" ] ; then
mv "$3" "$3.bak"
sed "s/$1/$2/g" "$3.bak" > "$3"
else
echo $3 not found
exit 1
fi

But it didn't...I think that -z is a problem...but really frustrated that I can't find why...my book doesn't help much :frowning:

In what way did it not work?

I'd do something like this:


if [ "$#" -lt 3 ]
then
        echo "usage:  a b file1 file2 ..."
        exit
fi

A=$1
shift
B=$1
shift
while [ "$#" -gt 0 ]
do
        echo "substitute $A for $B in $1"
        shift
done

Thanks for the code above, but I'm afraid my knowledge of shell script does not extend that far :(...I do not know how to use the while command or done. I'm vaguely familiar with shift as well...

When I inputted:

~/test/subst2 cat cow happy.txt

Even though there was no string "cat" in the file "happy.txt", it still created a .bak file...I am trying to make it so that if there is no string in the file that I am looking for to replace, then nothing will happen to the file.

Also there was a mistake in my code, the actual code in my "subst2" file is this:

#!/bin/sh

if [ -z "$3" ] ; then 
echo expect string1, string2, file
exit 1
fi 
if [ -f "$3" ] ; then
mv "$3" "$3.bak"
sed "s/$1/$2/g" "$3.bak" > "$3"
else
echo $3 not found
exit 1
fi  

the sed command is always going to execute if the value for $3 is a file. it will run a replace, which doesn't actually replace anything because the pattern doesn't match.

You need to add a check to see if the pattern passed in as $1 is found in the file before you run the sed and create the backup file


#!/bin/sh

if [ -z "$3" ] ; then 
echo expect string1, string2, file
exit 1
fi 
if [ -f "$3" -a "`/bin/grep "$1" "$3"`" ]; then
mv "$3" "$3.bak"
sed "s/$1/$2/g" "$3.bak" > "$3"
else
echo $3 not found
exit 1
fi

Ok, so I actually tried a different approach and it works, your code works great too :smiley:

#!/bin/bash
if grep "$1" "$3" > /dev/null; then
mv $3 $3.bak
sed "s/$1/$2/g" $3.bak > $3
fi

However, i can't find a way now to generalize my subst2 script, which would produce a new script "subst" that will apply a substitution to any number of files given on the command line.

For example...~/test/subst happy cow myFile1.txt myFile2.txt
myFile3.txt

should apply the same substitution throughout each of the three files named there.