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

···

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

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 Mon, Nov 19, 2007 at 11:38:08PM +0900, Shuaib Zahda wrote:

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 3:38 PM, Shuaib Zahda 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.

last_line = `tail -n 1 #{file_name}`

···

On Nov 19, 9:38 am, Shuaib Zahda <shuaib.za...@gmail.com> 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.

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

···

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

On Nov 19, 2007, at 3:38 PM, Shuaib Zahda 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

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

$ ruby -e 'p Enumerable === $stdin'
true

Cheers

robert

···

2007/11/19, Gregory Seidman <gsslist+ruby@anthropohedron.net>:

On Mon, Nov 19, 2007 at 11:38:08PM +0900, Shuaib Zahda 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 } }

--
use.inject do |as, often| as.you_can - without end

Good!

···

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

http://search.cpan.org/~uri/File-ReadBackwards-1.04/ReadBackwards.pm

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

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

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 Tue, Nov 20, 2007 at 12:41:46AM +0900, Robert Klemme wrote:

2007/11/19, Gregory Seidman <gsslist+ruby@anthropohedron.net>:
> On Mon, Nov 19, 2007 at 11:38:08PM +0900, Shuaib Zahda 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

James Gray wrote:

···

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

  http://search.cpan.org/~uri/File-ReadBackwards-1.04/ReadBackwards.pm

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

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

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

···

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

require "elif"

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

James Edward Gray II

···

On Nov 21, 2007, at 2:21 AM, Shuaib Zahda wrote:

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

James Gray wrote:

···

On Nov 21, 2007, at 2:21 AM, Shuaib Zahda 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 Gray 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
--
Posted via http://www.ruby-forum.com/\.

# 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

···

From: James Edward Gray II [mailto:james@grayproductions.net]

#
kind regards -botp

# 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

···

From: Shuaib Zahda [mailto:shuaib.zahda@gmail.com]

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

···

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

Peña, Botp wrote:

From: Shuaib Zahda [mailto:shuaib.zahda@gmail.com]
# 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

···

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

On Behalf Of Shuaib Zahda
# 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