1

I want to replace exact word by sed command with variable. My file looks like this:

//module xyz
module xyz 

Suppose I have the following shell variables defined:

var1='module xyz'
var2='module abc'

I want to change xyz to abc in uncommented line only(module xyz)

So after executing command output should be

//module xyz    
module abc

I do not want to change commented line (//module xyz)

currently I am using sed command as,

sed -i "s|$var1|$var2|g" file_name

But this command doesn't work. It also replace commented line. How can I only replace the line that isn't commented?

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
user5689562
  • 21
  • 1
  • 2

3 Answers3

0

Assuming that you know the pattern is at the start of the line, you can use this:

sed "s|^$var1|$var2|" file_name

That is, add an anchor ^, so that the match has to be at the start of the line.

I removed the -i switch so you can test it and also the g modifier, which isn't necessary as you only want to do one substitution per line.

It's worth mentioning that using shell variables in sed is actually quite tricky to do in a reliable way, so you should take this into account.

Community
  • 1
  • 1
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
0
  • Your shell variable assignment should be quoted if there is space. Like:

    var1="foo bar blah"
    
  • You can add pattern, "the lines don't start with // " to your sed command, so that do your substitution only for those lines

This line should work for your example:

sed -i "\@^//@\!s/$var1/$var2/g" file
  • the ! needs to be escaped, because we used double quote
  • since your pattern (comment) has slash (/), I used other char as regex separator
  • This command will only do substitution on lines not starting with //. If there are leading spaces, you may want to adjust the pattern ^//
Kent
  • 189,393
  • 32
  • 233
  • 301
0

You need to identify a pattern so that lines containing that pattern should not be processed. Assuming that // will exist only in commented lines you can use

sed -i '/\/\// !s/$var1/$var2/g' file_name

/\/\// will enable sed to identify lines which contain the pattern //, and !s will enable you to skip those lines.

Pintu
  • 278
  • 1
  • 6