| Author |
Message |
sunburnt

Joined: 08 Jun 2005 Posts: 4001 Location: Arizona, U.S.A.
|
Posted: Thu 27 Apr 2006, 22:45 Post subject:
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.
|
|
Back to top
|
|
 |
MU

Joined: 24 Aug 2005 Posts: 13642 Location: Karlsruhe, Germany
|
Posted: Thu 27 Apr 2006, 23:05 Post subject:
|
|
you will have to work with a copy.
cat thefile | sed "s/oldtext/newtext/" > thefile.new && mv thefile.new thefile
sed "s///" will be a standard sed-replacement.
Mark
|
|
Back to top
|
|
 |
rarsa

Joined: 29 May 2005 Posts: 3053 Location: Kitchener, Ontario, Canada
|
Posted: Thu 27 Apr 2006, 23:15 Post subject:
|
|
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
| Code: | | sed -e 's/\(SERVERID=\).\+/\1$NAME/" inputfile.txt > outputfile.txt |
Of course if you want to match the full line you can include the full line
| Code: | | sed -e 's/\(append root=\/dev\/ram0 initrd=image.gz ramdisk_size=16198 SERVERID=\).\+/\1$NAME/' testfile.txt > outputfile.txt |
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)
_________________ http://rarsa.blogspot.com Covering my eclectic thoughts
http://www.kwlug.org/blog/48 Covering my Linux How-to
Last edited by rarsa on Fri 28 Apr 2006, 09:40; edited 3 times in total
|
|
Back to top
|
|
 |
BarryK
Puppy Master

Joined: 09 May 2005 Posts: 6855 Location: Perth, Western Australia
|
Posted: Thu 27 Apr 2006, 23:34 Post subject:
|
|
Also, puppy2 alpha snapshot of 28th April has bash-diff, which is
bash on steroids -- has string handling stuff, but I haven't had a chance
to look at it. Puppy2 has a help page for bash-diff, also there's an announcement
on the developer news page.
|
|
Back to top
|
|
 |
sunburnt

Joined: 08 Jun 2005 Posts: 4001 Location: Arizona, U.S.A.
|
Posted: Fri 28 Apr 2006, 03:38 Post subject:
|
|
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.
|
|
Back to top
|
|
 |
MU

Joined: 24 Aug 2005 Posts: 13642 Location: Karlsruhe, Germany
|
Posted: Fri 28 Apr 2006, 06:03 Post subject:
|
|
| Quote: | | This isn't going to copy the entire contense of file 1 to file 2 with the change, is it? |
Yes it will.
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
|
|
Back to top
|
|
 |
rarsa

Joined: 29 May 2005 Posts: 3053 Location: Kitchener, Ontario, Canada
|
Posted: Fri 28 Apr 2006, 09:46 Post subject:
|
|
| sunburnt wrote: | | I guessing to copy the whole file a READ WHILE loop is needed & IF [grep] for the line to sed change? | 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.
_________________ http://rarsa.blogspot.com Covering my eclectic thoughts
http://www.kwlug.org/blog/48 Covering my Linux How-to
|
|
Back to top
|
|
 |
sunburnt

Joined: 08 Jun 2005 Posts: 4001 Location: Arizona, U.S.A.
|
Posted: Fri 28 Apr 2006, 16:56 Post subject:
|
|
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.
|
|
Back to top
|
|
 |
Dougal

Joined: 19 Oct 2005 Posts: 2505 Location: Hell more grotesque than any medieval woodcut
|
Posted: Sat 29 Apr 2006, 06:11 Post subject:
|
|
Just a comment:
Sed buffers it's input so you can redirect back into the same file:
| Code: | | cat myfile.txt | sed 's/apple/banana/g' >myfile.txt |
Will change all your apples into bananas! (it worked for me with a 20,000 line file)
|
|
Back to top
|
|
 |
Dougal

Joined: 19 Oct 2005 Posts: 2505 Location: Hell more grotesque than any medieval woodcut
|
Posted: Sun 30 Apr 2006, 05:39 Post subject:
|
|
Ahhhhh! I made a mistake.
Here's how I did it:
| Code: | | echo "`sed s/apple/banana/g myfile`" >myfile |
(Yes, I know the sed command isn't quoted)
|
|
Back to top
|
|
 |
sunburnt

Joined: 08 Jun 2005 Posts: 4001 Location: Arizona, U.S.A.
|
Posted: Sun 30 Apr 2006, 16:16 Post subject:
|
|
Dougal; Yep, it works a couple of ways, that's what my Bash book showed, but no cat command (it didn't work).
I've updated my app with your code, the PupServer setup GUI now writes to 6 config. files.
|
|
Back to top
|
|
 |
|