Как получить конкретную строку из файла - PullRequest
17 голосов
/ 25 октября 2010

Можно ли извлечь конкретную строку из файла, зная его номер строки?Например, просто получить содержимое строки N в виде строки из файла "text.txt"?

Ответы [ 6 ]

22 голосов
/ 25 октября 2010

Вы можете получить его по индексу от readlines.

line = IO.readlines("file.txt")[42]

Используйте это, только если это маленький файл.

14 голосов
/ 25 октября 2010

Попробуйте одно из этих двух решений:

file = File.open "file.txt"

#1 solution would eat a lot of RAM
p [*file][n-1]

#2 solution would not
n.times{ file.gets }
p $_

file.close
4 голосов
/ 25 октября 2010
def get_line_from_file(path, line)
  result = nil

  File.open(path, "r") do |f|
    while line > 0
      line -= 1
      result = f.gets
    end
  end

  return result
end

get_line_from_file("/tmp/foo.txt", 20)

Это хорошее решение, потому что:

  • Вы не используете File.read, поэтому вы не читаете весь файл в память.Это может стать проблемой, если размер файла составляет 20 МБ, и вы читаете достаточно часто, поэтому GC не успевает за ним.
  • Вы только читаете из файла до нужной строки.Если ваш файл имеет 1000 строк, то получение строки 20 будет считывать только первые 20 строк в Ruby.

Вы можете заменить gets на readline, если хотите вызвать ошибку (EOFError) вместо возврата за ноль при прохождении за пределами линии.

3 голосов
/ 25 октября 2010

Файл имеет хороший lineno метод.

def get_line(filename, lineno)
  File.open(filename,'r') do |f|
     f.gets until f.lineno == lineno - 1
     f.gets
  end
end
2 голосов
/ 25 октября 2010
linenumber=5
open("file").each_with_index{|line,ind|
  if  ind+1==linenumber
    save=line
    # break or exit if needed.
  end
}

или

linenumber=5
f=open("file")
while line=f.gets
  if $. == linenumber # $. is line number
    print "#{f.lineno} #{line}" # another way
    # break  # break or exit if needed
  end
end
f.close

Если вы просто хотите получить линию и больше ничего не делать, вы можете использовать этот вкладыш

ruby -ne '(print $_ and exit) if $.==5' file
0 голосов
/ 26 октября 2010

Если вы хотите один вкладыш и не заботитесь об использовании памяти, используйте (при условии, что строки нумеруются с 1)

lineN = IO.readlines('text.txt')[n-1]

или

lineN = f.readlines[n-1]

если файл уже открыт.

В противном случае было бы лучше сделать так:

lineN = File.open('text.txt') do |f|
          (n-1).times { f.gets } # skip lines preceeding line N
          f.gets                 # read line N contents
        end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...