Forum: Ruby Ruby way to update a file in place

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
73700e119917433681f2e8f3e4369f74?d=identicon&s=25 Li CN (alex-osu3)
on 2007-06-11 21:41
Hi all,

I just wonder what is the Ruby way to update a file in place. Do I need
to open a temporary/new file for writing and then rename the temporary
file?

Thanks,

Li
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (Guest)
on 2007-06-11 21:55
(Received via mailing list)
On Jun 11, 1:42 pm, Li Chen <chen_...@yahoo.com> wrote:
> Hi all,
>
> I just wonder what is the Ruby way to update a file in place. Do I need
> to open a temporary/new file for writing and then rename the temporary
> file?

That's the usual way. The other way is to use mmap.

Regards,

Dan
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2007-06-11 22:05
(Received via mailing list)
Li Chen wrote:
> Hi all,
>
> I just wonder what is the Ruby way to update a file in place. Do I need
> to open a temporary/new file for writing and then rename the temporary
> file?

You can open with the "r+" file mode, and use seek/rewind to move to a
position within the file, use #truncate to end the file, and so on.

[~/tmp] cat >foo
foo
bar
baz
[~/tmp] irb
irb(main):001:0> f = File.open("foo", "r+")
=> #<File:foo>
irb(main):002:0> f.puts "FOO"
=> nil
irb(main):003:0> f.seek 8
=> 0
irb(main):004:0> f.puts "BAZ"
=> nil
irb(main):005:0> f.rewind
=> 0
irb(main):006:0> f.read
=> "FOO\nbar\nBAZ\n"
irb(main):007:0> f.close
=> nil
irb(main):008:0> [~/tmp] cat foo
FOO
bar
BAZ
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-06-11 22:06
(Received via mailing list)
On 6/11/07, Li Chen <chen_li3@yahoo.com> wrote:
> --
> Posted via http://www.ruby-forum.com/.
>
No not necessarily, that depends how you can access the file, you can
use Ruby as an inplace filter on a file

ruby -i.bup -ne 'puts $_.gsub(/foo/,"bar")' somefile

will edit somefile and create a backup copy somefile.bup of the
original. Now when it comes to using files inside an application
things are little bit more complicated :(

HTH
Robert
7e593ac63e5f25649b701dc25f69d1b7?d=identicon&s=25 Luis Parravicini (Guest)
on 2007-06-11 22:09
(Received via mailing list)
On 6/11/07, Li Chen <chen_li3@yahoo.com> wrote:
> I just wonder what is the Ruby way to update a file in place. Do I need
> to open a temporary/new file for writing and then rename the temporary
> file?

There is also the '-i' argument to ruby. The example is from the man
page:
================================
% echo matz > /tmp/junk
% cat /tmp/junk
matz
% ruby -p -i.bak -e "$_.upcase!" /tmp/junk
% cat /tmp/junk
MATZ
% cat /tmp/junk.bak
matz
================================
73700e119917433681f2e8f3e4369f74?d=identicon&s=25 Li CN (alex-osu3)
on 2007-06-11 22:55
Where can I find some information about mmap?

thanks,

Li
Ff63c03fd68754adbadd2c6314646bef?d=identicon&s=25 Bill Guindon (agorilla)
on 2007-06-11 23:12
(Received via mailing list)
On 6/11/07, Li Chen <chen_li3@yahoo.com> wrote:
> Where can I find some information about mmap?

Google is your friend...
http://www.google.com/search?source=ig&hl=en&q=rub...

http://raa.ruby-lang.org/project/mmap/
2f5c0f4501526070f1df8a01b210b6b5?d=identicon&s=25 barjunk (Guest)
on 2007-06-12 00:25
(Received via mailing list)
On Jun 11, 1:11 pm, "Bill Guindon" <agori...@gmail.com> wrote:
> > Li
>
> > --
> > Posted viahttp://www.ruby-forum.com/.
>
> --
> Bill Guindon (aka aGorilla)
> The best answer to most questions is "it depends".

Although it may be wrong, I recently used lockfile and temporary files
to do inline editing.  It is probably inefficient, but it seems to
work for what I am using it for.

Maybe someone can point out how to use the -i feature of ruby from
within the program instead of  a shell command, that would work nice
as well.

In the application I was working on, there were possibilities for
multiple access at the same time.

Mike B.
C5b0a0cf40eb23497068889c8fb20a18?d=identicon&s=25 lrlebron@gmail.com (Guest)
on 2007-06-12 04:26
(Received via mailing list)
On Jun 11, 2:42 pm, Li Chen <chen_...@yahoo.com> wrote:
> --
> Posted viahttp://www.ruby-forum.com/.

I've used the rio library for this before. http://rio.rubyforge.org/.
The website has some very good examples on how to use it.

Luis
2f5c0f4501526070f1df8a01b210b6b5?d=identicon&s=25 barjunk (Guest)
on 2007-06-12 08:15
(Received via mailing list)
On Jun 11, 6:23 pm, "lrleb...@gmail.com" <lrleb...@gmail.com> wrote:
> > Li
>
> > --
> > Posted viahttp://www.ruby-forum.com/.
>
> I've used the rio library for this before.http://rio.rubyforge.org/.
> The website has some very good examples on how to use it.
>
> Luis

That's a nice library...I didn't notice any thing about locking the
file object.  I'm assuming that that would be done outside the use of
the rio object.

I was also wondering if you thought you could use that library to read
files that have records that look like:

start line 1
line 2
line 3
end line4

and treat the above four lines as a record?

Mike B.
C5b0a0cf40eb23497068889c8fb20a18?d=identicon&s=25 lrlebron@gmail.com (Guest)
on 2007-06-12 19:06
(Received via mailing list)
On Jun 12, 1:10 am, barjunk <barj...@attglobal.net> wrote:
> > > file?
>
> line 2
> line 3
> end line4
>
> and treat the above four lines as a record?
>
> Mike B.

I used it to clean up some code that was converted from vb6 to vb.net
The converter left a bunch of comments in the code that started with
"UPGRADE". I also went ahead and change the old "On Error Go To
Handler", "ErrHandler", and "Resume Next" strings to vb.net's "Try",
"Catch ex as Exception" and "End Try" strings

This is what the code looks like

require 'rio'
rio('C://test').all.files('*.vb') do |f|
   rio(f) <f.contents.gsub(/'UPGRADE.*\s/,"").gsub(/On Error GoTo
ErrHandler/,"Try").gsub(/ErrHandler:/,"Catch ex as Exception\n").gsub(/
Resume Next/,"End Try")
end

The second line tells rio to look at all the files ending in .vb in
the C://test folder
The third line does a string substitution in the currently open file

BTW, it was very fast.


Luis
C5b0a0cf40eb23497068889c8fb20a18?d=identicon&s=25 lrlebron@gmail.com (Guest)
on 2007-06-12 19:11
(Received via mailing list)
On Jun 12, 1:10 am, barjunk <barj...@attglobal.net> wrote:
> > > file?
>
> line 2
> line 3
> end line4
>
> and treat the above four lines as a record?
>
> Mike B.

Here's an example of using rio
require 'rio'
rio('C://test').all.files('*.vb') do |f|
   rio(f) <f.contents.gsub(/'UPGRADE.*\s/,"").gsub(/On Error GoTo
ErrHandler/,"Try").gsub(/ErrHandler:/,"Catch ex as Exception\n").gsub(/
Resume Next/,"End Try")
end


I had converted a bunch of vb6 files to vb.net. The VS2005 convertor
added hundreds of comment lines that started with 'UPGRADE. I also
wanted to change the vb6 Exception handlers
On Error GoTo ErrHandler
ErrHandler
Resume Next

to the vb.net format of
Try
Catch ex as Exception
End Try

This little snippet of code did the trick very quickly.

Luis
This topic is locked and can not be replied to.