Chris Illusion
Chris Illusion

Reputation: 287

Ruby - how to read first n lines from file into array

For some reason, I can't find any tutorial mentioning how to do this... So, how do I read the first n lines from a file?

I've come up with:

while File.open('file.txt') and count <= 3 do |f|
  ...
    count += 1
  end
end

but it is not working and it also doesn't look very nice to me.

Just out of curiosity, I've tried things like:

File.open('file.txt').10.times do |f|

but that didn't really work either.

So, is there a simple way to read just the first n lines without having to load the whole file? Thank you very much!

Upvotes: 12

Views: 12228

Answers (5)

iNulty
iNulty

Reputation: 923

File inherits from IO and IO mixes in Enumerable methods which include #first

Passing an integer to first(n) will return the first n items in the enumerable collection. For a File object, each item is a line in the file.

File.open('filename.txt', 'r').first(10)

This returns an array of the lines including the \n line breaks. You may want to #join them to create a single whole string.

File.open('filename.txt', 'r').first(10).join

Upvotes: 1

Darth Egregious
Darth Egregious

Reputation: 20106

You could try the following:

`head -n 10 file`.split

It's not really "pure ruby" but that's rarely a requirement these days.

Upvotes: -1

David Grayson
David Grayson

Reputation: 87541

Here is a one-line solution:

lines = File.foreach('file.txt').first(10)

I was worried that it might not close the file in a prompt manner (it might only close the file after the garbage collector deletes the Enumerator returned by File.foreach). However, I used strace and I found out that if you call File.foreach without a block, it returns an enumerator, and each time you call the first method on that enumerator it will open up the file, read as much as it needs, and then close the file. That's nice, because it means you can use the line of code above and Ruby will not keep the file open any longer than it needs to.

Upvotes: 32

infused
infused

Reputation: 24367

There are many ways you can approach this problem in Ruby. Here's one way:

File.open('Gemfile') do |f|
  lines = 10.times.map { f.readline }
end

Upvotes: 5

jack
jack

Reputation: 172

File.foreach('file.txt').with_index do |line, i|
    break if i >= 10
    puts line
end

Upvotes: 3

Related Questions