我试图使用以下代码从文件中读取行。但是在读取 file 时,内容都在一行中:
line_num=0
File.open('xxx.txt').each do |line|
print "#{line_num += 1} #{line}"
end
但是这个 file 分别打印每一行。
我必须使用标准输入,例如 ruby my_prog.rb < file.txt
,我不能假设文件使用的行尾字符是什么。我该如何处理?
line_num = 0
,您还可以使用 each.each_with_index
或可能使用 each.with_index
。
read
。
line.chomp
处理行尾(由 @SreenivasanAC 提供)
Ruby 确实有一个方法:
File.readlines('foo').each do |line|
puts(line)
end
http://ruby-doc.org/core-1.9.3/IO.html#method-c-readlines
File.foreach(filename).with_index do |line, line_num|
puts "#{line_num}: #{line}"
end
这将为文件中的每一行执行给定的块,而不会将整个文件放入内存中。请参阅:IO::foreach。
'filename'
而不是 filename
。也使用 line_num+1
而不是 line_num
,因此第一行从 1
开始,而不是在 0
。
filename
是一个包含 'xxx.txt'
等字符串的变量。
我相信我的回答涵盖了您对处理任何类型的行尾的新担忧,因为 "\r\n"
和 "\r"
在解析行之前都转换为 Linux 标准 "\n"
。
要支持 "\r"
EOL 字符以及 Windows 中的常规 "\n"
和 "\r\n"
,我将执行以下操作:
line_num=0
text=File.open('xxx.txt').read
text.gsub!(/\r\n?/, "\n")
text.each_line do |line|
print "#{line_num += 1} #{line}"
end
当然,这对于非常大的文件可能不是一个好主意,因为这意味着将整个文件加载到内存中。
/\r?\n/
它将涵盖 \r\n 和 \n 而不会像 Pod 的评论那样组合空行
您的第一个文件具有 Mac Classic 行尾(即 "\r"
而不是通常的 "\n"
)。打开它
File.open('foo').each(sep="\r") do |line|
指定行尾。
对于具有标题的文件,我偏爱以下方法:
File.open(file, "r") do |fh|
header = fh.readline
# Process the header
while(line = fh.gets) != nil
#do stuff
end
end
这允许您以不同于内容行的方式处理标题行(或行)。
这是因为每一行都有结束线。使用 ruby 中的 chomp 方法删除末尾的结束行 '\n' 或 'r'。
line_num=0
File.open('xxx.txt').each do |line|
print "#{line_num += 1} #{line.chomp}"
end
不要忘记,如果您担心读取的文件可能包含可能在运行时占用您的 RAM 的大行,您可以随时读取文件。请参阅“Why slurping a file is bad”。
File.open('file_path', 'rb') do |io|
while chunk = io.read(16 * 1024) do
something_with_the chunk
# like stream it across a network
# or write it to another file:
# other_io.write chunk
end
end
with_index
吗?File.readlines(filename).each_with_index { |line, i| puts "#{i}: #{line}" }