# Changing a file inline on Windows

**URL:** <https://www.ruby-forum.com/t/changing-a-file-inline-on-windows/141119>\
**Category:** Ruby\
**Created:** [June 22, 2008, 6:18am UTC](https://www.ruby-forum.com/t/changing-a-file-inline-on-windows/141119 "2008-06-22T06:18:21Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jimdeuc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b77776/32.png) [@jimdeuc](https://www.ruby-forum.com/u/jimdeuc)\
**Post date:** [June 22, 2008, 6:18am UTC](https://www.ruby-forum.com/t/changing-a-file-inline-on-windows/141119/1 "2008-06-22T06:18:21Z")

</div>

Here is my current method for editing files:

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

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

---

<div class="post-metadata">

**Author:** ![jimdeuc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b77776/32.png) [@jimdeuc](https://www.ruby-forum.com/u/jimdeuc)\
**Post date:** [June 22, 2008, 12:08pm UTC](https://www.ruby-forum.com/t/changing-a-file-inline-on-windows/141119/2 "2008-06-22T12:08:15Z")

</div>

On 22.06.2008 06:16, James D. wrote:

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

---

<div class="post-metadata">

**Author:** ![jimdeuc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b77776/32.png) [@jimdeuc](https://www.ruby-forum.com/u/jimdeuc)\
**Post date:** [June 23, 2008, 5:20am UTC](https://www.ruby-forum.com/t/changing-a-file-inline-on-windows/141119/3 "2008-06-23T05:20:47Z")

</div>

You can use the rio library to simplify this

require ‘rio’  
rio(f) \<f.contents.gsub(/six/,“half a dozen”)

---

<div class="post-metadata">

**Author:** ![jimdeuc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b77776/32.png) [@jimdeuc](https://www.ruby-forum.com/u/jimdeuc)\
**Post date:** [June 23, 2008, 1:25pm UTC](https://www.ruby-forum.com/t/changing-a-file-inline-on-windows/141119/4 "2008-06-23T13:25:54Z")

</div>

On Jun 21, 11:16 pm, James D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> content.collect! do |line|  
> 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-forum.com/.

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

---

<div class="post-metadata">

**Author:** ![jimdeuc](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b77776/32.png) [@jimdeuc](https://www.ruby-forum.com/u/jimdeuc)\
**Post date:** [June 23, 2008, 3:50pm UTC](https://www.ruby-forum.com/t/changing-a-file-inline-on-windows/141119/5 "2008-06-23T15:50:21Z")

</div>

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

James
