Read last line of a file

Hi all

I was trying to find a method to read only the last line of a file. I
checked the the documentation and there is no such method.
Beside reading line after line and checking the the eof method. Is there
any faster or shorter way to do that.

Regards

On Mon, Nov 19, 2007 at 11:38:08PM +0900, Shuaib Z. wrote:

Hi all

I was trying to find a method to read only the last line of a file. I
checked the the documentation and there is no such method.
Beside reading line after line and checking the the eof method. Is there
any faster or shorter way to do that.

Depending on your platform, you might find that using popen with tail -1
will be the fastest and easiest way. Failing that, consider this:

last = File.open(myfile) { |f| f.extend(Enumerable).inject { |_,ln| ln }
}

Regards
–Greg

On Nov 19, 2007, at 3:38 PM, Shuaib Z. wrote:

I was trying to find a method to read only the last line of a file. I
checked the the documentation and there is no such method.
Beside reading line after line and checking the the eof method. Is
there
any faster or shorter way to do that.

In Perl there’s File::ReadBackwards:

File::ReadBackwards - Read a file backwards by lines. - metacpan.org

The idea is that you put the file object in binmode and pick a chunk
of bytes towards the end of the file using for example

file.seek(-chunk_size_in_bytes, IO::SEEK_END)

and see whether the last (or last-but-one) line separator is there. If
it is not, step a bit backwards and try again.

– fxn

On Nov 19, 2007, at 9:07 AM, Xavier N. wrote:

File::ReadBackwards - Read a file backwards by lines. - metacpan.org
I ported this library as a solution to an old quiz:

Ruby Quiz - Port a Library (#64)

It’s a gem now, so you can do:

gem install elif

James Edward G. II

2007/11/19, Gregory S. [email protected]:

last = File.open(myfile) { |f| f.extend(Enumerable).inject { |_,ln| ln } }

You do not need the “.extend(Enumerable)” bit as an IO does already
include Enumerable:

$ ruby -e ‘p Enumerable === $stdin’
true

Cheers

robert

On Tue, Nov 20, 2007 at 12:41:46AM +0900, Robert K. wrote:

will be the fastest and easiest way. Failing that, consider this:

last = File.open(myfile) { |f| f.extend(Enumerable).inject { |_,ln| ln } }

You do not need the “.extend(Enumerable)” bit as an IO does already
include Enumerable:

$ ruby -e ‘p Enumerable === $stdin’
true

Ah, sorry, you are correct. For some reason I was thinking of MySQL
result
sets.

Cheers
robert
–Greg

On Nov 19, 2007, at 4:18 PM, James Edward G. II wrote:

File::ReadBackwards - Read a file backwards by lines. - metacpan.org

I ported this library as a solution to an old quiz:

Ruby Quiz - Port a Library (#64)

It’s a gem now, so you can do:

gem install elif

Good!

Shuaib Z. wrote:

Hi
Sorry for posting late

I was trying to figure out how to use this method but I failed. Can u
please give me an example

It works just like File#each, except in reverse order…

http://elif.rubyforge.org/ for documentation.

You could also just do something like this…

File.readlines(file).reverse_each {

But of course, that reads the whole file into an array first, so I would
still to using elif.

Regards,
Lee

On Nov 21, 2007, at 2:21 AM, Shuaib Z. wrote:

I was trying to figure out how to use this method but I failed. Can u
please give me an example

require “elif”

last_line = Elif.open(path) { |f| f.gets }

James Edward G. II

Hi
Sorry for posting late

I was trying to figure out how to use this method but I failed. Can u
please give me an example

James G. wrote:

On Nov 19, 2007, at 9:07 AM, Xavier N. wrote:

File::ReadBackwards - Read a file backwards by lines. - metacpan.org
I ported this library as a solution to an old quiz:

Ruby Quiz - Port a Library (#64)

It’s a gem now, so you can do:

gem install elif

James Edward G. II

James G. wrote:

On Nov 21, 2007, at 2:21 AM, Shuaib Z. wrote:

I was trying to figure out how to use this method but I failed. Can u
please give me an example

require “elif”

last_line = Elif.open(path) { |f| f.gets }

James Edward G. II

Thanks it works. But when i used require “elif”. My ruby did not
recognize its path. So i copied it into my local directory and ran it
fine. Is there any path issue that i have to tackle when i download new
package from gem. I am using ubuntu 7.10

Regards

On Nov 19, 9:38 am, Shuaib Z. [email protected] wrote:

Hi all

I was trying to find a method to read only the last line of a file. I
checked the the documentation and there is no such method.
Beside reading line after line and checking the the eof method. Is there
any faster or shorter way to do that.

last_line = tail -n 1 #{file_name}

From: Shuaib Z. [mailto:[email protected]]

Thanks it works. But when i used require “elif”. My ruby did not

recognize its path. So i copied it into my local directory and ran it

fine. Is there any path issue that i have to tackle when i

download new package from gem. I am using ubuntu 7.10

try,
require ‘rubygems’

gems require rubygems to find themselves :slight_smile:
require is change thereupon…

:~$ irb

~> alias old_require require
=> nil

~> require ‘units’
LoadError: no such file to load – units

~> old_require ‘units’
LoadError: no such file to load – units

~> require ‘rubygems’
=> true

~> old_require ‘units’
LoadError: no such file to load – units

~> require ‘units’
=> true

short story: only rubygems knows where the gems are :slight_smile:

~> puts lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 6.06.1 LTS
Release: 6.06
Codename: dapper
=> nil

kind regards -botp

Peña, Botp wrote:

From: Shuaib Z. [mailto:[email protected]]

Thanks it works. But when i used require “elif”. My ruby did not

recognize its path. So i copied it into my local directory and ran it

fine. Is there any path issue that i have to tackle when i

download new package from gem. I am using ubuntu 7.10

try,
require ‘rubygems’

gems require rubygems to find themselves :slight_smile:
require is change thereupon…

Thanks a lot. It works well. So, I can conclude that I have to call
rubygems then I call the elif.

Regards

From: James Edward G. II [mailto:[email protected]]

require “elif”

last_line = Elif.open(path) { |f| f.gets }

cool.

wc reminds me, i’m looking for a gem that reverses the behaviour of
string/collection/io/ traversals, like

#file reverse
require “in_reverse”
last_line = File.open(path).in_reverse { |f| f.gets }

#array reverse
%w(this is a test).each.in_reverse {|x| p x}
test
a
is
this

#string reverse
“this is a test”.each_char.in_reverse {|c| p c; break if c==“a”}
t
s
e
t

a

kind regards -botp

On Nov 21, 2007, at 10:26 PM, Peña, Botp wrote:

wc reminds me, i’m looking for a gem that reverses the behaviour of
string/collection/io/ traversals, like

#array reverse
%w(this is a test).each.in_reverse {|x| p x}
test
a
is
this

This can be hard to support for all iterators, but Array does have
reverse_each():

%w[this is a test].reverse_each { |word| puts word }
test
a
is
this
=> [“this”, “is”, “a”, “test”]

James Edward G. II

On Behalf Of Shuaib Z.

So, I can conclude that I have to call rubygems then I call the elif.

yes, and for any gem you want to load for that matter.

but if you always need a gem, you can create an env var RUBYOPT and set
it to rubygems, like

export RUBYOPT=rubygems

note that i seldom do this since rubygems loads a lot of things (observe
your $"). i wish rubygems has something like,

require “rubygems-base”

wc just installs the basic gem needed to find the needed gem paths…

kind regards -botp