Some file operations

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!

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:

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|
  (1..25).each {|num| file.puts("line #{num}")}
end

count = 0
File.open("data.txt") do |file|
  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|
    lines_arr.each do |line|
      file.write(line)
    end
end

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

#Display the result:

File.open("data.txt") do |file|
  file.each do |line|
    print line
  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|
  file.each do |line|
    if last_line
      temp_file.write(last_line)
    end

    last_line = line
  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/\.

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

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

Probably the easiest code for this is:

   line_count = 0
   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:

   line_count = 0
   File.open(ARGV.shift) do |f|
     while block = f.read(1024)
       line_count += block.count("\n")
     end
   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).

   Firefly:~/Desktop$ cat edit_last_line.rb
   #!/usr/bin/env ruby -wKU

   require "rubygems"
   require "elif"

   file = ARGV.shift

   # read the last line
   last_line = Elif.open(file) { |f| f.gets }

   # remove it from the file
   File.truncate(file, File.size(file) - last_line.size)

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

   __END__
   Firefly:~/Desktop$ cat data.txt
   The quick brown fox
   jumped over
   the lazy dog.
   Firefly:~/Desktop$ ruby edit_last_line.rb data.txt
   Firefly:~/Desktop$ cat data.txt
   The quick brown fox
   jumped over
   the sleeping dog.

Hope that helps.

James Edward Gray II

···

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

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

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|
  file.each do |line|
    if last_line
      temp_file.write(last_line)
    end

    last_line = line
  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|
  file.each do |line|
    if previous_line
      temp_file.write(previous_line)
    end

    previous_line = line
  end
end

previous_line = "hello world\n"
temp_file.write(previous_line)
temp_file.close()

···

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

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

···

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