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!

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

Bioinformatics Center
Kyoto University

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

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

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.

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

On 9/26/07, blufur [email protected] wrote:

Maybe a unix command that could be run by the ruby script that magically
gives you last line of a file

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.

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

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

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 G. II