我正在努力解决如何从Ruby CSV中获取当前的行号.这是我的代码:
options = {:encoding => 'UTF-8', :skip_blanks => true}
CSV.foreach("data.csv", options, ) do |row, i|
puts i
end
但这似乎并不像预期的那样有效.有办法做到这一点吗?
我正在努力解决如何从Ruby CSV中获取当前的行号.这是我的代码:
options = {:encoding => 'UTF-8', :skip_blanks => true}
CSV.foreach("data.csv", options, ) do |row, i|
puts i
end
但这似乎并不像预期的那样有效.有办法做到这一点吗?
Because of changes in CSV in current Rubies, we need to make some changes. See farther down in the answer for the original solution with Ruby prior to 2.6. and the use of 100 which continues to work regardless of the version.
For 2.6+ this'll work:
require 'csv'
puts RUBY_VERSION
csv_file = CSV.open('test.csv')
csv_file.each do |csv_row|
puts '%i %s' % [csv_file.lineno, csv_row]
end
csv_file.close
如果我读到:
Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very Large""","",5000.00
1996,Jeep,Grand Cherokee,"MUST SELL!\nair, moon roof, loaded",4799.00
代码将产生以下输出:
2.6.3
1 ["Year", "Make", "Model", "Description", "Price"]
2 ["1997", "Ford", "E350", "ac, abs, moon", "3000.00"]
3 ["1999", "Chevy", "Venture \"Extended Edition\"", "", "4900.00"]
4 ["1999", "Chevy", "Venture \"Extended Edition, Very Large\"", "", "5000.00"]
5 ["1996", "Jeep", "Grand Cherokee", "MUST SELL!\\nair, moon roof, loaded", "4799.00"]
更改是因为我们必须访问当前文件句柄.以前我们可以使用global $.
,它总是有失败的可能性,因为global可能会被调用代码的其他部分踩到.如果我们有被打开文件的句柄,那么我们可以使用lineno
而不必担心这个问题.
$.
Ruby prior to 2.6 would let us do this:
Ruby有一个magic variable $.
,它是正在读取的当前文件的行号:
require 'csv'
CSV.foreach('test.csv') do |csv|
puts $.
end
我得到上面的代码:
1
2
3
4
5
$INPUT_LINE_编号
Perl中始终使用$.
.在Ruby中,建议我们使用以下方法来避免其"神奇"的一面:
require 'english'
puts $INPUT_LINE_编号
如果有必要处理字段中的嵌入线端,只需稍加修改即可轻松处理.假设CSV文件"test.CSV"包含一行,其中嵌入了新行:
Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4799.00
1999,Chevy,"Venture ""Extended Edition, Very Large""","",5000.00
带_的索引
使用Enumerator's 带_的索引(1)
可以很容易地跟踪CSV向块的屈服次数,有效地模拟使用$.
,但在读取处理线端所需的额外行时,尊重CSV的工作:
require 'csv'
CSV.foreach('test.csv', headers: true).带_的索引(1) do |row, ln|
puts '%-3d %-5s %-26s %s' % [ln, *row.values_at('Make', 'Model', 'Description')]
end
运行时,输出:
$ ruby test.rb
1 Ford E350 ac, abs, moon
2 Chevy Venture "Extended Edition"
3 Jeep Grand Cherokee MUST SELL!
air, moon roof, loaded
4 Chevy Venture "Extended Edition, Very Large"