search and replace the whole line

Hi,

I have this line in a file called test.cfg

SOURCEFILE=/usr/platform/sun4v/driver/file.cfg

But i have many occurances of "SOURCEFILE" in test.cfg , i need to search only for this line and replace that line with

SOURCEFILE=/usr/platform/sun4x/driver/file.cfg

again there are many occurences of sun4v in that file but i need to replace only in this line. I tried grep for "SOURCEFILE="and using perl -pi -e but it replaces wherever it finds "sun4v" but i want only on this line.

Please help me.

Thanks.

This is in the sed FAQ.

For GNU sed:

sed '0,/sun4v/s//sun4x/' filename

For other seds:

sed -e '1s/sun4v/sun4x/;t' -e '1,/sun4v/s//sun4x/' filename

I am not sure I totally understand what you want to replace and how to find it but if you want to replace the whole line you can do:

sed 's/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/SOURCEFILE=\/usr\/platform\/sun4x\/driver\/file.cfg/' test.cfg

Hi radoulov,

I tried your option but again it does replaces all the occurences of sun4v but i want to look for that line and replace the occurence only in that line.

Hi borgeh

I tried the same option with perl -pi -e as

perl -pi -e 'SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/SOURCEFILE=\/usr\/platform\/sun4x\/driver\/file.cfg/g' test.cfg

but for some reasons it didnt work too. Actually iam executing this script as a finish script when the machine is jumpstarted.
Once the machine is build i checked the file it had no changes, but if i execute it manually it does change.I couldnt figure out whats the problem.
Please help me.

Thanks for your suggestions.

Could you post a sample from your file?
What's your OS and sed version?

Oops, sorry, I had to insert the hole pattern :slight_smile:

sed -e '
1s#SOURCEFILE=/usr/platform/sun4v/driver/file.cfg#SOURCEFILE=/usr/platform/sun4x/driver/file.cfg#;t' -e\ 
'1,/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/s//SOURCEFILE=\/usr\/platform\/sun4x\/driver\/file.cfg/
' filename

And, of course (from the FAQ:)):

Hi,

The file looks like

SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

Similar to the above lines there are lots of variable declarations with the variable SUN4V

#SOURCEFILE_LOCATION---------------------------

SOURCEFILE=/usr/platform/sun4v/driver/file.cfg

I want to search only for this occurence and replace the sun4v with sun4x variable but not anywhere else

Iam not sure how to check the veriosn of sed. iam using solaris 8.

Thanks a lot.

This should be straightforward with my sed-suggestion above.

OK,
try this one:

sed '1,/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/s/4v/4x/' filename

P.S. Note that you may need to insert the whole pattern after the s command ...
ex:

sed '1,/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/s/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/SOURCEFILE=\/usr\/platform\/sun4x\/driver\/file.cfg/' filename

Hi,

Iam sorry but that one failed too. It replaced everywhere it found sun4v.
Is there anyway i could insert a comment ('#') in front of that line and append a new line with the new variable next to that line.

Like,

#SOURCEFILE=/usr/platform/sun4v/driver/file.cfg
SOURCEFILE=/usr/platform/sun4x/driver/file.cfg

Thanks for your help.

nawk '{
	if(!(checked)&&($0~/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/)){
		print "#"$0
		sub(/4v/,"4x")
		checked=1
		print 
	}else{
		print
		}
}' file

Hi,

Iam sorry i didnt see ur edited message.
Here's the command i tried

sed '1,/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/s/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/SOURCEFILE=\/usr\/platform\/sun4x\/driver\/file.cfg/' test.cfg

It returns nothing , the file remains unchanged.
Also i tried the nawk script the file remains unchanged and it prints the whole file with no changes in it.

Thanks for your help.

Hm,
may be there is an error in the pattern,
did you copy/paste-it in your post, or you modified it by hand?
Here is what I get:

$ uname -r
5.8
$ cat file
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

Similar to the above lines there are lots of variable declarations with the variable SUN4V

#SOURCEFILE_LOCATION---------------------------

SOURCEFILE=/usr/platform/sun4v/driver/file.cfg
SOURCEFILE=/usr/platform/sun4v/driver/file.cfg
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE
$ nawk '{
if(!(checked)&&($0~/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/)){
print "#"$0
sub(/4v/,"4x")
checked=1
print 
}else{
print
}
}' file
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

Similar to the above lines there are lots of variable declarations with the variable SUN4V

#SOURCEFILE_LOCATION---------------------------

#SOURCEFILE=/usr/platform/sun4v/driver/file.cfg
SOURCEFILE=/usr/platform/sun4x/driver/file.cfg
SOURCEFILE=/usr/platform/sun4v/driver/file.cfg
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

With sed:

$ sed '1,/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/s/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/SOURCEFILE=\/usr\/platform\/sun4x\/driver\/file.cfg/' file    
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

Similar to the above lines there are lots of variable declarations with the variable SUN4V

#SOURCEFILE_LOCATION---------------------------

SOURCEFILE=/usr/platform/sun4x/driver/file.cfg
SOURCEFILE=/usr/platform/sun4v/driver/file.cfg
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

The file will remain unchanged anyway,
you'll get only modified output.

Hi,

I get the same output now as you get, but i need to save the changes in the same file, so what can i do for that.

Thanks a lot for your help.

OK,
use this:

cp your_file your_file.orig

nawk '{
	if(!(checked)&&($0~/SOURCEFILE=\/usr\/platform\/sun4v\/driver\/file.cfg/)){
		print "#"$0
		sub(/4v/,"4x")
		checked=1
		print 
	}else{
		print
		}
}' your_file>new_file

mv new_file your_file

Great, that worked like a champ.

I have one last doubt. Suppose if i have a '*' symbol in the path like

SOURCEFILE=/usr/platform/sun4v*/driver/file.cfg

how should i give any escape character to include* too, so that i can replace sun4v* with sun4x.

Thanks again.

Like this:

cp your_file your_file.orig

nawk '{
	if(!(checked)&&($0~/SOURCEFILE=\/usr\/platform\/sun4v[*]\/driver\/file.cfg/)){
		print "#"$0
		sub(/4v[*]/,"4x")
		checked=1
		print 
	}else{
		print
		}
}' your_file>new_file

mv new_file your_file

For example:

$ cat file
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

Similar to the above lines there are lots of variable declarations with the variable SUN4V

#SOURCEFILE_LOCATION---------------------------

SOURCEFILE=/usr/platform/sun4v*/driver/file.cfg
SOURCEFILE=/usr/platform/sun4v*/driver/file.cfg
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE
$ nawk '{
if(!(checked)&&($0~/SOURCEFILE=\/usr\/platform\/sun4v[*]\/driver\/file.cfg/)){
print "#"$0
sub(/4v[*]/,"4x")
checked=1
print 
}else{
print
}
}' file
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

Similar to the above lines there are lots of variable declarations with the variable SUN4V

#SOURCEFILE_LOCATION---------------------------

#SOURCEFILE=/usr/platform/sun4v*/driver/file.cfg
SOURCEFILE=/usr/platform/sun4x/driver/file.cfg
SOURCEFILE=/usr/platform/sun4v*/driver/file.cfg
SUN4V_AVERAGE_MESSAGE_SIZE=128
SUN4V_MESSAGES_IN_INITIAL_RESPONSES=6500
SUN4V_ENFORCE_YIELD_NAMES=FALSE

No Problem, I figured it out.

Thanks a lot for your help.