HowTo: edit line in file, with bash code
HowTo: edit line in file, with bash code
The kernel argument line is a good example:
append root=/dev/ram0 initrd=image.gz ramdisk_size=16198 SERVERID=$NAME
I want to substitute $NAME for whatever was there first.
If the line were the only line in the file it wouldn't be as hard.
Substituting something in the middle of the line would be nice also.
append root=/dev/ram0 initrd=image.gz ramdisk_size=16198 SERVERID=$NAME
I want to substitute $NAME for whatever was there first.
If the line were the only line in the file it wouldn't be as hard.
Substituting something in the middle of the line would be nice also.
Use sed
For example, assuming that the text you want to replace is in a file called inputfile.txt then you can do the following
Of course if you want to match the full line you can include the full line
Here is the explanation of the command.
sed ---> the stream editor utility
-e --> you want to use the following script (the script will be between single or double quotes.
s/<orig>/<replace>/ --> this is the command to substitute whatever is matched as <orig> with <replace>
in my example
\(SERVERID=\).\+ is the <orig>. in this case a regular expression
\1$NAME is the <replace>
Now I will explain the regular expression,
The backslash is just an 'escape character' that indicates that the next command is not part of the string but a control character. In regular expressions anything that is between parenthesis is treated as a unit (or field). the first thing between parenthesis is field 1, the second is field 2, etc.
So the regular expression is saying that SERVERID= is a field. In this case field 1. The backslashes before the parenthesis are just saying that the parenthesis are not part of the string.
after that we have .\+
the . (dot) matches any character.
as I said before, the \ is saying that the + is not part of the string you are searching but a control character. in this case + means that you can have zero or more of the previous characters (in this case any character)
Now the replacement command \1$NAME
This is saying to insert field number one, followed by the contents of the variable NAME.
In simple terms, it is searching SERVERID=<whatever> and replacing it with SERVERID=$NAME.
I hope I didn't confuse you more. You can play with regular expressions using the Regexpview expression evaluator included with puppy (in the Utilities menu)
For example, assuming that the text you want to replace is in a file called inputfile.txt then you can do the following
Code: Select all
sed -e 's/\(SERVERID=\).\+/\1$NAME/" inputfile.txt > outputfile.txt
Code: Select all
sed -e 's/\(append root=\/dev\/ram0 initrd=image.gz ramdisk_size=16198 SERVERID=\).\+/\1$NAME/' testfile.txt > outputfile.txt
sed ---> the stream editor utility
-e --> you want to use the following script (the script will be between single or double quotes.
s/<orig>/<replace>/ --> this is the command to substitute whatever is matched as <orig> with <replace>
in my example
\(SERVERID=\).\+ is the <orig>. in this case a regular expression
\1$NAME is the <replace>
Now I will explain the regular expression,
The backslash is just an 'escape character' that indicates that the next command is not part of the string but a control character. In regular expressions anything that is between parenthesis is treated as a unit (or field). the first thing between parenthesis is field 1, the second is field 2, etc.
So the regular expression is saying that SERVERID= is a field. In this case field 1. The backslashes before the parenthesis are just saying that the parenthesis are not part of the string.
after that we have .\+
the . (dot) matches any character.
as I said before, the \ is saying that the + is not part of the string you are searching but a control character. in this case + means that you can have zero or more of the previous characters (in this case any character)
Now the replacement command \1$NAME
This is saying to insert field number one, followed by the contents of the variable NAME.
In simple terms, it is searching SERVERID=<whatever> and replacing it with SERVERID=$NAME.
I hope I didn't confuse you more. You can play with regular expressions using the Regexpview expression evaluator included with puppy (in the Utilities menu)
Last edited by rarsa on Fri 28 Apr 2006, 13:40, edited 3 times in total.
[url]http://rarsa.blogspot.com[/url] Covering my eclectic thoughts
[url]http://www.kwlug.org/blog/48[/url] Covering my Linux How-to
[url]http://www.kwlug.org/blog/48[/url] Covering my Linux How-to
Thanks to all... This will allow me to finish some PupServer script maintenance utilities.
MU; That's why it wouldn't work, I was writing to the same file.
This isn't going to copy the entire contense of file 1 to file 2 with the change, is it?
rarsa; That clarifies a lot! Same Q as MU...
I guessing to copy the whole file a READ WHILE loop is needed & IF [grep] for the line to sed change?
BarryK; Hmmm... Bash on steroids, sounds too good to be true, I'll definately take a look at it.
MU; That's why it wouldn't work, I was writing to the same file.
This isn't going to copy the entire contense of file 1 to file 2 with the change, is it?
rarsa; That clarifies a lot! Same Q as MU...
I guessing to copy the whole file a READ WHILE loop is needed & IF [grep] for the line to sed change?
BarryK; Hmmm... Bash on steroids, sounds too good to be true, I'll definately take a look at it.
Yes it will.This isn't going to copy the entire contense of file 1 to file 2 with the change, is it?
And after that, the "mv" moves the new file over the original one (replacing it).
To avoid that, you would need a "remotecontrolled" comandlineeditor like vi.
It can open a text, edit one line, then save the text back.
But I don't know how that works in detail, I just read about that once, and it looked too complicated to remember
Mark
Your guess is wrong. sed does the 'grep' part for you. That's why you pass the input file name as a parameter. It will parse the whole file and replace every single occurrence of the string matching the regular expression.sunburnt wrote:I guessing to copy the whole file a READ WHILE loop is needed & IF [grep] for the line to sed change?
[url]http://rarsa.blogspot.com[/url] Covering my eclectic thoughts
[url]http://www.kwlug.org/blog/48[/url] Covering my Linux How-to
[url]http://www.kwlug.org/blog/48[/url] Covering my Linux How-to
After testing it all out, I found that the cat command isn't needed:
sed -e "s/SERVERID=.*/SERVERID=pupserv/" test > new && mv new test && rm -f new
And the ".+" won't work in place of ".*", but the field substitution works great:
sed -e "s/\(SERVERID=\).*/\1pupserv/" test > new && mv new test && rm -f new
Thanks... I've found again that my Bash book isn't reliable, but there's so many versions & then there's BusyBox.
My script: xsetserver now sets 4 files to PupServer's name & IP add.
sed -e "s/SERVERID=.*/SERVERID=pupserv/" test > new && mv new test && rm -f new
And the ".+" won't work in place of ".*", but the field substitution works great:
sed -e "s/\(SERVERID=\).*/\1pupserv/" test > new && mv new test && rm -f new
Thanks... I've found again that my Bash book isn't reliable, but there's so many versions & then there's BusyBox.
My script: xsetserver now sets 4 files to PupServer's name & IP add.
- Dougal
- Posts: 2502
- Joined: Wed 19 Oct 2005, 13:06
- Location: Hell more grotesque than any medieval woodcut
Just a comment:
Sed buffers it's input so you can redirect back into the same file:
Will change all your apples into bananas! (it worked for me with a 20,000 line file)
Sed buffers it's input so you can redirect back into the same file:
Code: Select all
cat myfile.txt | sed 's/apple/banana/g' >myfile.txt
- Dougal
- Posts: 2502
- Joined: Wed 19 Oct 2005, 13:06
- Location: Hell more grotesque than any medieval woodcut
Ahhhhh! I made a mistake.
Here's how I did it:
(Yes, I know the sed command isn't quoted)
Here's how I did it:
Code: Select all
echo "`sed s/apple/banana/g myfile`" >myfile