HowTo: edit line in file, with bash code

How to do things, solutions, recipes, tutorials
Post Reply
Message
Author
User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

HowTo: edit line in file, with bash code

#1 Post by sunburnt »

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.

User avatar
MU
Posts: 13649
Joined: Wed 24 Aug 2005, 16:52
Location: Karlsruhe, Germany
Contact:

#2 Post by MU »

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

User avatar
rarsa
Posts: 3053
Joined: Sun 29 May 2005, 20:30
Location: Kitchener, Ontario, Canada
Contact:

#3 Post by rarsa »

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: Select all

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: Select all

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)
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

User avatar
BarryK
Puppy Master
Posts: 9392
Joined: Mon 09 May 2005, 09:23
Location: Perth, Western Australia
Contact:

#4 Post by BarryK »

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.

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#5 Post by sunburnt »

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.

User avatar
MU
Posts: 13649
Joined: Wed 24 Aug 2005, 16:52
Location: Karlsruhe, Germany
Contact:

#6 Post by MU »

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 :lol:

Mark

User avatar
rarsa
Posts: 3053
Joined: Sun 29 May 2005, 20:30
Location: Kitchener, Ontario, Canada
Contact:

#7 Post by rarsa »

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.
[url]http://rarsa.blogspot.com[/url] Covering my eclectic thoughts
[url]http://www.kwlug.org/blog/48[/url] Covering my Linux How-to

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#8 Post by sunburnt »

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.

User avatar
Dougal
Posts: 2502
Joined: Wed 19 Oct 2005, 13:06
Location: Hell more grotesque than any medieval woodcut

#9 Post by Dougal »

Just a comment:

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
Will change all your apples into bananas! (it worked for me with a 20,000 line file)

User avatar
Dougal
Posts: 2502
Joined: Wed 19 Oct 2005, 13:06
Location: Hell more grotesque than any medieval woodcut

#10 Post by Dougal »

Ahhhhh! I made a mistake.
Here's how I did it:

Code: Select all

echo "`sed s/apple/banana/g myfile`" >myfile
(Yes, I know the sed command isn't quoted)

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#11 Post by sunburnt »

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.

Post Reply