# Some file operations

**URL:** <https://rubytalk.org/t/some-file-operations/40958>\
**Category:** ruby-talk\
**Created:** [27 September 2007 03:23 UTC](https://rubytalk.org/t/some-file-operations/40958 "2007-09-27T03:23:21Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dan](https://avatars.discourse-cdn.com/v4/letter/d/eada6e/32.png) [@Dan](https://rubytalk.org/u/Dan)\
**Post date:** [27 September 2007 03:23 UTC](https://rubytalk.org/t/some-file-operations/40958/1 "2007-09-27T03:23:21Z")

</div>

A couple quick questions:

how can my ruby program tell me how many lines are in a text file?

how can i have my ruby program edit the last line of a text file (not add another line at the end, but get and then change the line at the end).

Thanks for any suggestions!

---

<div class="post-metadata">

**Author:** ![Alex\_Gutteridge](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@Alex\_Gutteridge](https://rubytalk.org/u/Alex_Gutteridge)\
**Post date:** [27 September 2007 04:31 UTC](https://rubytalk.org/t/some-file-operations/40958/2 "2007-09-27T04:31:15Z")

</div>

> how can my ruby program tell me how many lines are in a text file?

IO.foreach iterates over the lines in a file which you can then count, or IO.read reads the whole thing into a string from which you can then count the number of lines.

> how can i have my ruby program edit the last line of a text file (not add another line at the end, but get and then change the line at the end).

Easiest (IMO) is to read the whole file, edit the last line and write back out. E.g:

lines = IO.read('file').split  
lines[-1] = 'edit'  
puts lines

> Thanks for any suggestions!

Alex Gutteridge

Bioinformatics Center  
Kyoto University

> **···**
>
> On 27 Sep 2007, at 12:23, blufur wrote:

---

<div class="post-metadata">

**Author:** ![7stud1](https://avatars.discourse-cdn.com/v4/letter/7/59ef9b/32.png) [@7stud1](https://rubytalk.org/u/7stud1)\
**Post date:** [27 September 2007 05:14 UTC](https://rubytalk.org/t/some-file-operations/40958/3 "2007-09-27T05:14:52Z")

</div>

blufur wrote:

> A couple quick questions:
> 
> how can my ruby program tell me how many lines are in a text file?
> 
> how can i have my ruby program edit the last line of a text file (not  
> add another line at the end, but get and then change the line at the  
> end).

#Read the file and count the lines:

File.open("data.txt", "w") do |file|  
&nbsp;&nbsp;(1..25).each {|num| file.puts("line #{num}")}  
end

count = 0  
File.open("data.txt") do |file|  
&nbsp;&nbsp;file.each {count += 1}  
end

puts count #25

#To change the last line of a file that isn't  
#extremely large:

lines\_arr = IO.readlines("data.txt")  
lines\_arr[-1] = "hello world\n"

File.open("temp.txt", "w") do |file|  
&nbsp;&nbsp;&nbsp;&nbsp;lines\_arr.each do |line|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.write(line)  
&nbsp;&nbsp;&nbsp;&nbsp;end  
end

File.delete("data.txt")  
File.rename("temp.txt", "data.txt")

#Display the result:

File.open("data.txt") do |file|  
&nbsp;&nbsp;file.each do |line|  
&nbsp;&nbsp;&nbsp;&nbsp;print line  
&nbsp;&nbsp;end  
end

--output--  
line 1  
line 2  
line 3  
...  
...  
line 23  
line 24  
hello world

For extremely large files on the order of 1-2GB, you can try something  
like this:

last\_line = nil  
temp\_file = File.new("temp.txt", "w")

File.open("data.txt") do |file|  
&nbsp;&nbsp;file.each do |line|  
&nbsp;&nbsp;&nbsp;&nbsp;if last\_line  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp\_file.write(last\_line)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;last\_line = line  
&nbsp;&nbsp;end  
end

last\_line = "hello world\n"  
temp\_file.write(last\_line)  
temp\_file.close()

#Delete and rename as above

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Alex\_Young](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@Alex\_Young](https://rubytalk.org/u/Alex_Young)\
**Post date:** [27 September 2007 07:11 UTC](https://rubytalk.org/t/some-file-operations/40958/4 "2007-09-27T07:11:43Z")

</div>

blufur wrote:

> A couple quick questions:
> 
> how can my ruby program tell me how many lines are in a text file?

If it's huge, `wc -l` is probably best.

> **···**
>
> > how can i have my ruby program edit the last line of a text file (not add another line at the end, but get and then change the line at the end).
> > 
> > Thanks for any suggestions!
> 
> --  
> Alex

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [27 September 2007 12:56 UTC](https://rubytalk.org/t/some-file-operations/40958/5 "2007-09-27T12:56:23Z")

</div>

> how can my ruby program tell me how many lines are in a text file?

Probably the easiest code for this is:

&nbsp;&nbsp;&nbsp;line\_count = 0  
&nbsp;&nbsp;&nbsp;File.foreach(…) { line\_count = $. }

That's not too great performance-wise on huge files though. We can optimize the reads to speed it up a little:

&nbsp;&nbsp;&nbsp;line\_count = 0  
&nbsp;&nbsp;&nbsp;File.open(ARGV.shift) do |f|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while block = f.read(1024)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line\_count += block.count("\n")  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

That version is more than twice as fast on the 96 MB file I tried it on.

> how can i have my ruby program edit the last line of a text file (not add another line at the end, but get and then change the line at the end).

&nbsp;&nbsp;&nbsp;Firefly:~/Desktop$ cat edit\_last\_line.rb  
&nbsp;&nbsp;&nbsp;#!/usr/bin/env ruby -wKU

&nbsp;&nbsp;&nbsp;require "rubygems"  
&nbsp;&nbsp;&nbsp;require "elif"

&nbsp;&nbsp;&nbsp;file = ARGV.shift

&nbsp;&nbsp;&nbsp;# read the last line  
&nbsp;&nbsp;&nbsp;last\_line = Elif.open(file) { |f| f.gets }

&nbsp;&nbsp;&nbsp;# remove it from the file  
&nbsp;&nbsp;&nbsp;File.truncate(file, File.size(file) - last\_line.size)

&nbsp;&nbsp;&nbsp;# replace the line  
&nbsp;&nbsp;&nbsp;File.open(file, "a") { |f| f.puts last\_line.sub(/\blazy\b/, "sleeping") }

&nbsp;&nbsp;&nbsp;\_\_END\_\_  
&nbsp;&nbsp;&nbsp;Firefly:~/Desktop$ cat data.txt  
&nbsp;&nbsp;&nbsp;The quick brown fox  
&nbsp;&nbsp;&nbsp;jumped over  
&nbsp;&nbsp;&nbsp;the lazy dog.  
&nbsp;&nbsp;&nbsp;Firefly:~/Desktop$ ruby edit\_last\_line.rb data.txt  
&nbsp;&nbsp;&nbsp;Firefly:~/Desktop$ cat data.txt  
&nbsp;&nbsp;&nbsp;The quick brown fox  
&nbsp;&nbsp;&nbsp;jumped over  
&nbsp;&nbsp;&nbsp;the sleeping dog.

Hope that helps.

James Edward Gray II

> **···**
>
> On Sep 26, 2007, at 10:23 PM, blufur wrote:

---

<div class="post-metadata">

**Author:** ![Dan](https://avatars.discourse-cdn.com/v4/letter/d/eada6e/32.png) [@Dan](https://rubytalk.org/u/Dan)\
**Post date:** [27 September 2007 04:39 UTC](https://rubytalk.org/t/some-file-operations/40958/6 "2007-09-27T04:39:23Z")

</div>

thanks for the suggestions - it is a very big file, though (many thousands of lines), and I have to do this many times in a loop. Any less resource-intensive way? Maybe a unix command that could be run by the ruby script that magically gives you last line of a file, then allows you to delete last line of file, then i can just append new to file?

Best,  
DAN

> **···**
>
> On Sep 27, 2007, at 12:31 AM, Alex Gutteridge wrote:
> 
> > On 27 Sep 2007, at 12:23, blufur wrote:
> > 
> > > how can my ruby program tell me how many lines are in a text file?
> > 
> > IO.foreach iterates over the lines in a file which you can then count, or IO.read reads the whole thing into a string from which you can then count the number of lines.
> > 
> > > how can i have my ruby program edit the last line of a text file (not add another line at the end, but get and then change the line at the end).
> > 
> > Easiest (IMO) is to read the whole file, edit the last line and write back out. E.g:
> > 
> > lines = IO.read('file').split  
> > lines[-1] = 'edit'  
> > puts lines
> > 
> > > Thanks for any suggestions!
> > 
> > Alex Gutteridge
> > 
> > Bioinformatics Center  
> > Kyoto University

---

<div class="post-metadata">

**Author:** ![7stud1](https://avatars.discourse-cdn.com/v4/letter/7/59ef9b/32.png) [@7stud1](https://rubytalk.org/u/7stud1)\
**Post date:** [27 September 2007 11:27 UTC](https://rubytalk.org/t/some-file-operations/40958/7 "2007-09-27T11:27:18Z")

</div>

7stud -- wrote:

> For extremely large files on the order of 1-2GB, you can try something  
> like this:
> 
> last\_line = nil  
> temp\_file = File.new("temp.txt", "w")
> 
> File.open("data.txt") do |file|  
> &nbsp;&nbsp;file.each do |line|  
> &nbsp;&nbsp;&nbsp;&nbsp;if last\_line  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp\_file.write(last\_line)  
> &nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;last\_line = line  
> &nbsp;&nbsp;end  
> end
> 
> last\_line = "hello world\n"  
> temp\_file.write(last\_line)  
> temp\_file.close()
> 
> #Delete and rename as above

A change of variable names would make it clearer what that code is  
doing:

previous\_line = nil  
temp\_file = File.new("temp.txt", "w")

File.open("data.txt") do |file|  
&nbsp;&nbsp;file.each do |line|  
&nbsp;&nbsp;&nbsp;&nbsp;if previous\_line  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp\_file.write(previous\_line)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;previous\_line = line  
&nbsp;&nbsp;end  
end

previous\_line = "hello world\n"  
temp\_file.write(previous\_line)  
temp\_file.close()

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Victor\_Reyes](https://avatars.discourse-cdn.com/v4/letter/v/ed655f/32.png) [@Victor\_Reyes](https://rubytalk.org/u/Victor_Reyes)\
**Post date:** [5 October 2007 11:04 UTC](https://rubytalk.org/t/some-file-operations/40958/8 "2007-10-05T11:04:36Z")

</div>

> how can my ruby program tell me how many lines are in a text file?

In UNIX:

v = `wc -l /etc/passwd`  
puts v

Victor

> **···**
>
> >

---

<div class="post-metadata">

**Author:** ![Daniel\_Brumbaugh\_Kee](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Brumbaugh\_Kee](https://rubytalk.org/u/Daniel_Brumbaugh_Kee)\
**Post date:** [5 October 2007 06:02 UTC](https://rubytalk.org/t/some-file-operations/40958/9 "2007-10-05T06:02:57Z")

</div>

I am relatively inexperienced in UNIX but the command  
tail -1 /path/to/file.ext  
should return the last line of any file. I don't know if there's any way to  
let you write to it.

> **···**
>
> On 9/26/07, blufur \<blufur@gmail.com\> wrote:
> 
> > Maybe a unix command that could be run by the ruby script that magically  
> > gives you last line of a file
> 
> -------------------------------------------  
> Daniel Brumbaugh Keeney  
> Devi Web Development  
> Devi.WebMaster@gMail.com  
> -------------------------------------------
