2009-09-29 13 views
50

Voglio leggere solo la prima riga di un file che utilizza Ruby nel modo più veloce, più semplice e più idiomatico possibile. Qual è l'approccio migliore?Leggere la prima riga di un file in Ruby

(In particolare: voglio leggere l'UUID di commit git fuori dal file REVISION nella mia ultima directory Rails distribuita da Capistrano, e quindi inviarlo al mio tag. Questo mi consentirà di vedere a un http-glance quale versione è schierati al mio server Se c'è un tipo completamente diverso & modo migliore per fare questo, per favore fatemelo sapere)

risposta

93

questo leggerà esattamente una riga e garantire che il file sia correttamente chiuso immediatamente dopo.

File.open('somefile.txt') {|f| f.readline} 
# or, in Ruby 1.8.7 and above: # 
File.open('somefile.txt', &:readline) 
3
first_line = open("filename").gets 
7

si può provare questo:..

File.foreach('path_to_file').first 
+0

LocalJumpError: nessun blocco dato – klochner

+3

@klochner: Il tuo Ruby è vecchio. Funziona bene in 1.8.7 e sopra. – Chuck

+0

Mi spiace, Vincent, non posso rimuovere il downvote a meno che tu non faccia qualche modifica minore. – klochner

5

Come leggere la prima riga di un file ruby:

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

In alternativa si può solo fare un git-log da dentro l'applicazione:

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

% h racconta il formato per stampare l'hash del commit completo. Ci sono anche moduli che ti permettono di accedere al tuo repository git locale all'interno di un'app Rails in un modo più ruby-ish anche se non li ho mai usati.

+0

.last non funziona come programmato qui. Come faccio questo per l'ultima riga? –

1

Penso che il suggerimento di jkupferman di investigare le opzioni git --pretty abbia più senso, tuttavia un altro approccio sarebbe il comando head ad es.

ruby -e 'puts `head -n 1 filename`' #(backtick before `head` and after `filename`) 
+0

https://gist.github.com/784711 – maletor

15

Ecco un modo conciso idiomatica per farlo che si apre correttamente il file per la lettura e lo chiude successivamente.

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

Se si desidera che un file vuoto causi un'eccezione, utilizzare invece questa.

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

Inoltre, ecco un rapido & sporca implementazione di testa che avrebbe funzionato per i vostri scopi e in molti altri casi in cui si desidera leggere un paio di righe.

# 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 
+1

Implementazione più semplice: 'file di classe; def self.head (path, n = 1); foreach (percorso) .first (n); fine; fine' –

+1

(6 anni dopo ....) Cosa sta succedendo in quei primi 2 esempi con il simbolo come secondo argomento da aprire? Non riesco a trovare alcun documento che spieghi cosa sta facendo. Thx per qualsiasi informazione ... – skydvr

2

first_line = File.readlines('file_path').first.chomp

+1

Anche se funziona, ma non caricherà l'intero file in memoria? – Saim

2

Migliorare sulla risposta inviato da @Chuck, penso che potrebbe essere utile far notare che se il file che state leggendo è vuoto, verrà generata un'eccezione EOFError. Cattura e ignorare l'eccezione:

def readit(filename) 
text = "" 
begin 
    text = File.open(filename, &:readline) 
rescue EOFError 
end 
text 
end 
Problemi correlati