[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

changing a file inline on Windows

James Dinkel

6/22/2008 4:17:00 AM

Here is my current method for editing files:

<code>

filename = File.join('path', 'to', 'file')
content = []
File.open(filename, 'r') do |file|
content = file.readlines
end

content.collect! do |line|
line.gsub!(/six/, "half a dozen")
line.chomp
end

File.open(filename, 'w') do |file|
file.write content.join($/)
end

</code>

This is expensive though, as it rewrites the entire file, even if only a
single word in the whole file is changed. I'm wondering if there is a
better way to do this.

James
--
Posted via http://www.ruby-....

4 Answers

Robert Klemme

6/22/2008 10:04:00 AM

0

On 22.06.2008 06:16, James Dinkel wrote:
> Here is my current method for editing files:
>
> <code>
>
> filename = File.join('path', 'to', 'file')
> content = []
> File.open(filename, 'r') do |file|
> content = file.readlines
> end
>
> content.collect! do |line|
> line.gsub!(/six/, "half a dozen")
> line.chomp
> end
>
> File.open(filename, 'w') do |file|
> file.write content.join($/)

This is a killer because it will transform the whole file into a single
String just for printing. You better do either of this

1. just do "file.puts content"

2. work with String the whole way, i.e.

content = File.read file_name
content.gsub! /six/, "half a dozen"
File.open(file_name, "w") {|io| io.write content}

First alternative has the advantage of being a smaller change to your
code and also I believe it's nicer to the GC; second solution has the
advantage that you can do multiline replacements.

> end
>
> </code>
>
> This is expensive though, as it rewrites the entire file, even if only a
> single word in the whole file is changed. I'm wondering if there is a
> better way to do this.

For text files the situation is usually this: the replacement has
different length than the original. Thus, you need to at least rewrite
all the stuff from the original string's starting position on. The code
becomes a bit more complex and if the file is small it's probably not
worthwhile.

Note also that there is command line option -i which will allow for easy
inline edits:

ruby -i.bak -pe 'gsub /six/, "half a dozen"' your_file

You can also use it in scripts:

#!/bin/ruby -i.bak -p
gsub /six/, "half a dozen"

Kind regards

robert

lrlebron@gmail.com

6/23/2008 3:18:00 AM

0

You can use the rio library to simplify this

require 'rio'
rio(f) <f.contents.gsub(/six/,"half a dozen")


On Jun 21, 11:16 pm, James Dinkel <jdin...@gmail.com> wrote:
> Here is my current method for editing files:
>
> <code>
>
>   filename = File.join('path', 'to', 'file')
>   content = []
>   File.open(filename, 'r') do |file|
>     content = file.readlines
>   end
>
>   content.collect! do |line|
>     line.gsub!(/six/, "half a dozen")
>     line.chomp
>   end
>
>   File.open(filename, 'w') do |file|
>     file.write content.join($/)
>   end
>
> </code>
>
> This is expensive though, as it rewrites the entire file, even if only a
> single word in the whole file is changed.  I'm wondering if there is a
> better way to do this.
>
> James
> --
> Posted viahttp://www.ruby-....

lrlebron@gmail.com

6/23/2008 11:20:00 AM

0

On Jun 21, 11:16 pm, James Dinkel <jdin...@gmail.com> wrote:
> Here is my current method for editing files:
>
> <code>
>
>   filename = File.join('path', 'to', 'file')
>   content = []
>   File.open(filename, 'r') do |file|
>     content = file.readlines
>   end
>
>   content.collect! do |line|
>     line.gsub!(/six/, "half a dozen")
>     line.chomp
>   end
>
>   File.open(filename, 'w') do |file|
>     file.write content.join($/)
>   end
>
> </code>
>
> This is expensive though, as it rewrites the entire file, even if only a
> single word in the whole file is changed.  I'm wondering if there is a
> better way to do this.
>
> James
> --
> Posted viahttp://www.ruby-....

There was a small error in my previous post. Here a more complete
script

require 'rio'
ario = rio(filename)
ario < ario.contents.gsub(/six/, "half a dozen")

James Dinkel

6/23/2008 1:49:00 PM

0

Thanks for all the information. I'll try out these methods and try to
get an idea which one I like best.

James
--
Posted via http://www.ruby-....