0

Homework - don't just throw me an answer, but I've literally been stuck on this for days. That also explains why I'm stuck using csh, which is of course exacerbating the problem.

The shell script needs to search a file for a string and replace it with a new string, creating a backup file if the string has been found and the file has been altered. Simple enough, right?

Here's my code.

    #!/bin/csh                                                                     
set currentWord=$1
set newWord=$2
set fileName=$3

#sed -i.bak -e  "s/$1/$2/g" $3                                                  

  if  (grep -q $1 $3)  then
     sed -i.bak -e "s/$1/$2/g" $3
   else
     echo "The string is not found."
   endif

The problem I'm running into is that it's not supposed to "touch" the file unless the string is found. The way I've been doing it creates the file either way, sometimes they just end up being identical files. I've tried by only using one sed command as well, but the closest I've gotten to the solution is by working the sed command into an if then else. Now I'm getting an "if expression syntax" error - which is making me think I can't use grep like that at all and need to reformat it or use something else.

1 Answers1

0

You need to check the exit status of grep. And there are a couple of ways to do so.

You either:

call grep and then examine the special variable $status, like in

#!/bin/csh

set currentWord=$1
set newWord=$2
set fileName=$3

grep -q $currentWord $fileName

if !($status) then
    sed -i.bak -e "s/$currentWord/$newWord/g" $fileName
else
    echo "The string is not found."
endif

or, since the actual vale of $status is not needed here, just use the terser form

#!/bin/csh

set currentWord=$1
set newWord=$2
set fileName=$3

if { grep -q $currentWord $fileName } then
    sed -i.bak -e "s/$currentWord/$newWord/g" $fileName
else
    echo "The string is not found."
endif

The second one is my favourite.

Roberto Reale
  • 4,247
  • 1
  • 17
  • 21
  • Thank you so much, the second option worked like a charm. Exactly what I was trying to accomplish except I kept borking it. – user3569949 Apr 24 '14 at 18:14
  • You could also just pipeline the two - `grep -q $currentWord $fileName && sed -i.bak -e "s/$currentWord/$newWord/g" $filename`. That would only run the `sed` command if the `grep` command indicated success... – twalberg Apr 24 '14 at 19:08
  • Both the loops and pipe (@Twalberg) suggestions worked and now I find myself stuck again. Is there an easy way to accept unlimited specified files through standard input? Everything I'm trying either only accepts the first file (tweaking sed/grep) or runs every single file in that directory (wildcards/regex). Two hours in and I assume I'm over-complicating, once again. – user3569949 Apr 25 '14 at 15:57