是否可以从知道其行号的文件中提取特定行?例如,只需将行N
的内容作为文件“text.txt”中的字符串获取?
答案 0 :(得分:22)
您可以通过readlines
的索引获取它。
line = IO.readlines("file.txt")[42]
只有当它是一个小文件时才使用它。
答案 1 :(得分:14)
尝试以下两种解决方案之一:
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
答案 2 :(得分:4)
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
,因此您不会将整个文件读入内存。如果文件大小为20MB并且您经常阅读以便GC无法跟上,那么这样做可能会成为一个问题。如果您想提出错误(gets
)而不是在传递越界行时返回nil,则可以将readline
替换为EOFError
。
答案 3 :(得分:3)
文件有一个很好的lineno
方法。
def get_line(filename, lineno)
File.open(filename,'r') do |f|
f.gets until f.lineno == lineno - 1
f.gets
end
end
答案 4 :(得分:2)
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
答案 5 :(得分:0)
如果您想要一个衬垫并且不关心内存使用情况,请使用(假设线条从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
答案 6 :(得分:0)
如果您只希望文件中的一行,或者希望文件中的多行足够小以便重复读取,则可以使用这些解决方案。大型文件(例如,1000万行)需要花费更长的时间搜索特定的行,因此最好是一次读取就依次获取必要的行,这样就不会多次读取大型文件。
创建一个大文件:
File.open('foo', 'a') { |f| f.write((0..10_000_000).to_a.join("\n")) }
选择将从其中读取的行并确保对它们进行排序:
lines = [9_999_999, 3_333_333, 6_666_666].sort
打印出这些行:
File.open('foo') do |f|
lines.each_with_index do |line, index|
(line - (index.zero? ? 0 : lines[index - 1]) - 1).times { f.gets }
puts f.gets
end
end
此解决方案适用于任意数量的行,不会将整个文件加载到内存中,只会读取尽可能少的行,并且只能读取一次文件。