69

I want to read only the first line of a file using Ruby in the fastest, simplest, most idiomatic way possible. What's the best approach?

(Specifically: I want to read the git commit UUID out of the REVISION file in my latest Capistrano-deployed Rails directory, and then output that to my tag. This will let me see at an http-glance what version is deployed to my server. If there's an entirely different & better way to do this, please let me know.)

Craig Walker
  • 49,871
  • 54
  • 152
  • 212

8 Answers8

125

This will read exactly one line and ensure that the file is properly closed immediately after.

strVar = File.open('somefile.txt') {|f| f.readline}
# or, in Ruby 1.8.7 and above: #
strVar = File.open('somefile.txt', &:readline)
puts strVar
Julien Lamarche
  • 931
  • 1
  • 12
  • 29
Chuck
  • 234,037
  • 30
  • 302
  • 389
26

Here's a concise idiomatic way to do it that properly opens the file for reading and closes it afterwards.

File.open('path.txt', &:gets)

If you want an empty file to cause an exception use this instead.

File.open('path.txt', &:readline)

Also, here's a quick & dirty implementation of head that would work for your purposes and in many other instances where you want to read a few more lines.

# Reads a set number of lines from the top.
# Usage: File.head('path.txt')
class File
  def self.head(path, n = 1)
     open(path) do |f|
        lines = []
        n.times do
          line = f.gets || break
          lines << line
        end
        lines
     end
  end
end
Blake Taylor
  • 9,217
  • 5
  • 38
  • 41
  • 1
    Simpler implementation: `class File; def self.head(path, n = 1); foreach(path).first(n); end; end` – Nathan Long Nov 11 '14 at 14:23
  • 1
    (6 years later....) What is happening in those first 2 examples with the symbol as the second argument to open? I can't find any doc that explains what that's doing. Thx for any info... – skydvr Dec 14 '17 at 16:51
  • @skydvr read this https://stackoverflow.com/questions/14881125/what-does-to-proc-method-mean – Blair Anderson May 13 '20 at 15:13
7

You can try this:

File.foreach('path_to_file').first
Vincent
  • 4,883
  • 2
  • 25
  • 17
6

How to read the first line in a ruby file:

commit_hash = File.open("filename.txt").first

Alternatively you could just do a git-log from inside your application:

commit_hash = `git log -1 --pretty=format:"%H"`

The %H tells the format to print the full commit hash. There are also modules which allow you to access your local git repo from inside a Rails app in a more ruby-ish manner although I have never used them.

jkupferman
  • 610
  • 4
  • 7
5
first_line = open("filename").gets
Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
3

I think the jkupferman suggestion of investigating the git --pretty options makes the most sense, however yet another approach would be the head command e.g.

ruby -e 'puts `head -n 1 filename`'  #(backtick before `head` and after `filename`)
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Andrew Atkinson
  • 1,155
  • 8
  • 20
2
first_line = File.readlines('file_path').first.chomp
Ulysse BN
  • 10,116
  • 7
  • 54
  • 82
boblin
  • 3,541
  • 4
  • 25
  • 29
2

Improving on the answer posted by @Chuck, I think it might be worthwhile to point out that if the file you are reading is empty, an EOFError exception will be thrown. Catch and ignore the exception:

def readit(filename)
 text = ""
 begin
   text = File.open(filename, &:readline)
 rescue EOFError
 end
 text
end
markeissler
  • 649
  • 7
  • 9