Hello Master Scripters,
I am in scripting nursery and I am trying to write a script that will replace string a with string b. I can get my script to replace single strings with no problem, my issue arrives when one of my strings has two words. I am pretty sure that there are quotes involved for this. Now, can the quotes be in the script instead of being written in the command line. If I run my script with the quotes in the command line the script works perfectly.

My script currently looks like this:

#!/bin/csh
set stringa=$1
set stringb=$2
set filename=$3
sed s/$stringa/$stringb/g $filename

I have tried to run it with

set "stringa"=$1

, but this gives me a syntax error.
I have tried to run it with

set stringa="$1"

, and this seems to have the same effect as no quotes.
I tried also to run it with everything above the sed line without quotes and then the

sed s/"$stringa/"$stringb"/g $filename

, with no luck.

Any other suggestion on how to accomplish this task?

Dani AI

Generated

As already pointed out, the shell splits the command line on whitespace before your script ever runs. There is no way for the script to magically receive My House as a single argument unless the caller quotes or escapes it. That is the fundamental constraint; quoting on the command line is the simplest fix.

If you cannot change how the caller types the command, handle it inside the script by deciding how to reassemble the pieces. A common pattern is: treat the last argument as the filename, the next-to-last as the replacement, and join everything else into the search string. The snippet below shows that approach in csh and uses perl for a literal (non-regex) replacement so you do not have to worry about regex meta-characters in the search text.

# expects: old-words... new file
set ac = $#argv
if ($ac < 3) then
  echo "usage: old... new file"
  exit 1
endif

@ limit = $ac - 2
set file = $argv[$ac]
set new  = $argv[$ac-1]

set i = 1
set old = ""
while ( $i <= $limit )
  if ("$old" == "") then
    set old = "$argv[$i]"
  else
    set old = "$old $argv[$i]"
  endif
  @ i++
end

perl -0777 -pe "s/\Q$old\E/$new/g" "$file" > "$file".tmp && mv "$file".tmp "$file"

Notes and cautions: use \Q...\E in perl to avoid regex surprises; test on copies before overwriting real files. As noted, -i only controls in-place editing and will not change how the shell splits arguments. Also consider moving to a Bourne-compatible shell for scripting: sh/bash scripting gives clearer handling of positional parameters ("$@") and is generally safer than csh for non-interactive scripts.

Recommended Answers

All 5 Replies

what about sed "s/$stringa/$stringb/g" $filename ?

use -i parameter for sed
#i'm not csh user
sed -i "s/$stringa/$stringb/g" $filename
#and test if you have to make quoutes around $filename to
#if it doesn't help, try echo $stringa and $stringb before sed

what about sed "s/$stringa/$stringb/g" $filename ?

Negative, That didnt work wither. Whenever there is a space it takes the next word and puts it in the next available variable.

So, If I want to replace "My House" for Home in file mystory, and i type
$./scriptname My House Home mystory.txt

it sets $1 to "My" $2 to "House" and $3 to "Home", but $3 should be the filename in this case mystory.txt

I need to get it to do take this command:
$./scriptname My House Home mystory.txt

and set $1 to My House, $2 to Home and $3 to mystory.txt. Is this even possible without issuing the command like this:
$./scriptname "My House" Home mystory.txt ?

use -i parameter for sed
#i'm not csh user
sed -i "s/$stringa/$stringb/g" $filename
#and test if you have to make quoutes around $filename to
#if it doesn't help, try echo $stringa and $stringb before sed

I tried using the sed -i but I think its not an option in csh. I did the echo before sed, and sure enough it is showing the strings all messed up if one string has two or more words.

You do need the quotes around it. There's no way around that - the shell will automatically break it up into separate parameters. Afterall, there's no way for the shell to know the difference between ./script "My House" Home someFile and ./script My "House Home" someFile without the quotes being there.

And sed -i would not change the result, just the behavior of the substitution (changing the file in place rather than printing the result).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.