Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading/greping a file in ruby more than once

Tags:

file

ruby

How can I reset the "pointer" of a file to its start without reopening it? (Something like fseek in C?)

For example, I have a file that I want to grep for two patterns:

f=open('test') => #<File:test> 
f.grep(/llo/)  => ["Hello world\n"] 
f.grep(/wo/)   => [] 

Is it possible to reset f without reopening the file?

Note: I am not looking for workarounds; I can think some on my own ;).

like image 812
zakkak Avatar asked Oct 16 '12 15:10

zakkak


2 Answers

Take a look at the ruby docs for the IO class. To reset the stream:

f.pos = 0

or

f.seek 0

Note that you can also set the stream to an arbitrary byte position with these methods, but be careful if the file contains multibyte characters.

Tip: File.ancestors will tell you the inheritance chain so you can look up methods that might accomplish what you want (but you sometimes have to do more advanced reflection for singleton methods and method_missing).

UPDATE:

megas' answer may be cleaner because rewind also resets lineno. grep's output is not affected by the value of lineno, but lineno will get increasingly inaccurate unless it's reset. If you don't care about lineno, you can safely use either of our solutions.

like image 84
Kelvin Avatar answered Nov 16 '22 21:11

Kelvin


Use rewind

Positions ios to the beginning of input, resetting lineno to zero.

f = File.new("testfile") 
f.readline   #=> "This is line one\n"
f.rewind     #=> 0 
f.lineno     #=> 0 
f.readline   #=> "This is line one\n"
like image 34
megas Avatar answered Nov 16 '22 21:11

megas