Help with Writing Replacement Text to Files

Hello!

I'm new to ruby and been reading this very active list for about a couple of week.

I have a project at work where I need to write a simple script to scrub IP addresses from configuration files for classified networks we work in sometimes. The goal is to cleanse configuration files sometimes required for support of any specific network addressing information. Here is what I've come up with so far. While this works in IRB on the file object I create, I cannot figure out how to write the changes back in place to the actual file itself back on the regex I'm using:

  config_file = File.open("config.txt")
         config_txt = config_file.read
         config_txt.gsub!(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/, "000.000.000.000")

I do understand that the default action here is read-only. How to do I parse with the regex on the current file and replace matching strings without either appending to the file, overwriting the file, or creating a new file?

Thanks!

~Thomas

Try this:

File.open("config.txt", "rw") do |f|
  text = f.read
  text.gsub!(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/, "000.000.000.000")
  f.rewind
  f.write(text)
end

Using the block form like that will automagically close the file when
it ends. :slight_smile:

--Jeremy

···

On Feb 17, 2008 11:00 PM, Thomas Pierce <ruby@upgradeyourmind.com> wrote:

Hello!

I'm new to ruby and been reading this very active list for about a
couple of week.

I have a project at work where I need to write a simple script to
scrub IP addresses from configuration files for classified networks we
work in sometimes. The goal is to cleanse configuration files
sometimes required for support of any specific network addressing
information. Here is what I've come up with so far. While this works
in IRB on the file object I create, I cannot figure out how to write
the changes back in place to the actual file itself back on the regex
I'm using:

  config_file = File.open("config.txt")
         config_txt = config_file.read
         config_txt.gsub!(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
"000.000.000.000")

I do understand that the default action here is read-only. How to do I
parse with the regex on the current file and replace matching strings
without either appending to the file, overwriting the file, or
creating a new file?

Thanks!

~Thomas

--
http://jeremymcanally.com/
http://entp.com

Read my books:
Ruby in Practice (http://manning.com/mcanally/\)
My free Ruby e-book (http://humblelittlerubybook.com/\)

Or, my blogs:

http://rubyinpractice.com

Thomas,

I'm new to Ruby (only a few days) but this is something I think I can
actually help you with. I had to do some searching and I came across
this website ..
http://pleac.sourceforge.net/pleac_ruby/fileaccess.html

Search for 'Modifying a File in Place Without a Temporary File' and
you'll find the code. I'll paste it here though just to make it quick
and easy ..

File.open('itest', 'r+') do |f| # open file for update
    lines = f.readlines # read into array of lines
    lines.each do |it| # modify lines
        it.gsub!(/foo/, 'QQQ')
    end
    f.pos = 0 # back to start
    f.print lines # write out modified lines
    f.truncate(f.pos) # truncate to new length
end # file is automatically closed

r+ is the mode that allows you to read and write to the file. I made
a text file named itest with this for content ..

foo foo
bar bar
foo foo

I ran that code and the file got changed to ..

QQQ QQQ
bar bar
QQQ QQQ

That's what you're looking for isn't it? I would suggest making a
backup of the files just in case there is a problem. If that isn't
what you were looking for I apologize, reply back to this and I'll try
again haha.

···

--
-Andy
"I have a great faith in fools; self-confidence my friends call it." –
Edgar Allen Poe

On Feb 17, 2008 9:00 PM, Thomas Pierce <ruby@upgradeyourmind.com> wrote:

Hello!

I'm new to ruby and been reading this very active list for about a
couple of week.

I have a project at work where I need to write a simple script to
scrub IP addresses from configuration files for classified networks we
work in sometimes. The goal is to cleanse configuration files
sometimes required for support of any specific network addressing
information. Here is what I've come up with so far. While this works
in IRB on the file object I create, I cannot figure out how to write
the changes back in place to the actual file itself back on the regex
I'm using:

  config_file = File.open("config.txt")
         config_txt = config_file.read
         config_txt.gsub!(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
"000.000.000.000")

I do understand that the default action here is read-only. How to do I
parse with the regex on the current file and replace matching strings
without either appending to the file, overwriting the file, or
creating a new file?

Thanks!

~Thomas

Jeremy McAnally wrote:

Try this:

File.open("config.txt", "rw") do |f|

File.open('data.text', 'rw') do |f|
end

--output:--
r1test.rb:1:in `initialize': illegal access mode rw (ArgumentError)
        from r1test.rb:1:in `open'
        from r1test.rb:1

···

--
Posted via http://www.ruby-forum.com/\.

Andy/Jeremy

Thanks for the help!

Jeremy, I ran your code snippet first with "w+" and it wiped the whole file. I then ran the code snippet Andy provided and it worked. I went back and used "r+" instead of "w+" in the code you provided Jeremy and it worked as well.

I also appreciate the explanatory comments. Very helpful.

Both code snippets work and provide me with exactly what I need.

Thanks again.

Hopefully as I move along I'll be able to be just as helpful on this list.

Best Regards,

~Thomas

···

On Feb 17, 2008, at 11:38 PM, Andy wrote:

Thomas,

I'm new to Ruby (only a few days) but this is something I think I can
actually help you with. I had to do some searching and I came across
this website ..
File Access

Search for 'Modifying a File in Place Without a Temporary File' and
you'll find the code. I'll paste it here though just to make it quick
and easy ..

File.open('itest', 'r+') do |f| # open file for update
   lines = f.readlines # read into array of lines
   lines.each do |it| # modify lines
       it.gsub!(/foo/, 'QQQ')
   end
   f.pos = 0 # back to start
   f.print lines # write out modified lines
   f.truncate(f.pos) # truncate to new length
end # file is automatically closed

r+ is the mode that allows you to read and write to the file. I made
a text file named itest with this for content ..

foo foo
bar bar
foo foo

I ran that code and the file got changed to ..

QQQ QQQ
bar bar
QQQ QQQ

That's what you're looking for isn't it? I would suggest making a
backup of the files just in case there is a problem. If that isn't
what you were looking for I apologize, reply back to this and I'll try
again haha.

--
-Andy
"I have a great faith in fools; self-confidence my friends call it." –
Edgar Allen Poe

On Feb 17, 2008 9:00 PM, Thomas Pierce <ruby@upgradeyourmind.com> > wrote:

Hello!

I'm new to ruby and been reading this very active list for about a
couple of week.

I have a project at work where I need to write a simple script to
scrub IP addresses from configuration files for classified networks we
work in sometimes. The goal is to cleanse configuration files
sometimes required for support of any specific network addressing
information. Here is what I've come up with so far. While this works
in IRB on the file object I create, I cannot figure out how to write
the changes back in place to the actual file itself back on the regex
I'm using:

config_file = File.open("config.txt")
        config_txt = config_file.read
        config_txt.gsub!(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
"000.000.000.000")

I do understand that the default action here is read-only. How to do I
parse with the regex on the current file and replace matching strings
without either appending to the file, overwriting the file, or
creating a new file?

Thanks!

~Thomas

Oops. Try "w+" instead.

*has Python/PHP file read modes on the brain*

--Jeremy

···

On Feb 18, 2008 1:55 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:

Jeremy McAnally wrote:
> Try this:
>
> File.open("config.txt", "rw") do |f|
>

File.open('data.text', 'rw') do |f|
end

--output:--
r1test.rb:1:in `initialize': illegal access mode rw (ArgumentError)
        from r1test.rb:1:in `open'
        from r1test.rb:1
--
Posted via http://www.ruby-forum.com/\.

--
http://jeremymcanally.com/
http://entp.com

Read my books:
Ruby in Practice (http://manning.com/mcanally/\)
My free Ruby e-book (http://humblelittlerubybook.com/\)

Or, my blogs:

http://rubyinpractice.com

Oh, right. I forget that the "*+" modes do the primary letter ("w"
wipes the file for example) first, then "add on" the functionality of
the other (this must show how much I actually use those modes, eh?
:)). Well, glad to help nonetheless.

--Jeremy

···

On Feb 18, 2008 9:35 AM, Thomas Pierce <ruby@upgradeyourmind.com> wrote:

Andy/Jeremy

Thanks for the help!

Jeremy, I ran your code snippet first with "w+" and it wiped the whole
file. I then ran the code snippet Andy provided and it worked. I went
back and used "r+" instead of "w+" in the code you provided Jeremy and
it worked as well.

I also appreciate the explanatory comments. Very helpful.

Both code snippets work and provide me with exactly what I need.

Thanks again.

Hopefully as I move along I'll be able to be just as helpful on this
list.

Best Regards,

~Thomas

On Feb 17, 2008, at 11:38 PM, Andy wrote:

> Thomas,
>
> I'm new to Ruby (only a few days) but this is something I think I can
> actually help you with. I had to do some searching and I came across
> this website ..
> File Access
>
> Search for 'Modifying a File in Place Without a Temporary File' and
> you'll find the code. I'll paste it here though just to make it quick
> and easy ..
>
> File.open('itest', 'r+') do |f| # open file for update
> lines = f.readlines # read into array of lines
> lines.each do |it| # modify lines
> it.gsub!(/foo/, 'QQQ')
> end
> f.pos = 0 # back to start
> f.print lines # write out modified lines
> f.truncate(f.pos) # truncate to new length
> end # file is automatically closed
>
> r+ is the mode that allows you to read and write to the file. I made
> a text file named itest with this for content ..
>
> foo foo
> bar bar
> foo foo
>
> I ran that code and the file got changed to ..
>
> QQQ QQQ
> bar bar
> QQQ QQQ
>
> That's what you're looking for isn't it? I would suggest making a
> backup of the files just in case there is a problem. If that isn't
> what you were looking for I apologize, reply back to this and I'll try
> again haha.
>
> --
> -Andy
> "I have a great faith in fools; self-confidence my friends call it." –
> Edgar Allen Poe
>
> On Feb 17, 2008 9:00 PM, Thomas Pierce <ruby@upgradeyourmind.com> > > wrote:
>> Hello!
>>
>> I'm new to ruby and been reading this very active list for about a
>> couple of week.
>>
>> I have a project at work where I need to write a simple script to
>> scrub IP addresses from configuration files for classified networks
>> we
>> work in sometimes. The goal is to cleanse configuration files
>> sometimes required for support of any specific network addressing
>> information. Here is what I've come up with so far. While this works
>> in IRB on the file object I create, I cannot figure out how to write
>> the changes back in place to the actual file itself back on the regex
>> I'm using:
>>
>> config_file = File.open("config.txt")
>> config_txt = config_file.read
>> config_txt.gsub!(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
>> "000.000.000.000")
>>
>> I do understand that the default action here is read-only. How to
>> do I
>> parse with the regex on the current file and replace matching strings
>> without either appending to the file, overwriting the file, or
>> creating a new file?
>>
>> Thanks!
>>
>> ~Thomas
>>
>>
>

--
http://jeremymcanally.com/
http://entp.com

Read my books:
Ruby in Practice (http://manning.com/mcanally/\)
My free Ruby e-book (http://humblelittlerubybook.com/\)

Or, my blogs:

http://rubyinpractice.com