Ruby CSV。これは私のコードです。
options = {:encoding => 'UTF-8', :skip_blanks => true}
CSV.foreach("data.csv", options, ) do |row, i|
puts i
end
しかし、これは期待どおりに機能しないようです。これを行う方法はありますか?
現在のルビーではCSVが変更されているため、いくつかの変更を加える必要があります。 Ruby 2.6より前の元のソリューションと、バージョンに関係なく機能し続ける_with_index
_の使用に関する元のソリューションの回答を参照してください。
2.6+の場合、これは機能します:
_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"]
_
変更は、現在のファイルハンドルにアクセスする必要があるためです。以前は、グローバル_$.
_を使用できましたが、これは、呼び出されたコードの他のセクションによってグローバルが踏みつけられる可能性があるため、常に失敗の可能性がありました。開かれているファイルのハンドルがあれば、その心配なしにlineno
を使用できます。
$.
_2.6より前のRubyではこれが可能です:
Rubyには マジック変数_$.
_ があり、これは現在読み込まれているファイルの行番号です:
_require 'csv'
CSV.foreach('test.csv') do |csv|
puts $.
end
_
上記のコードで、私は得る:
_1
2
3
4
5
_
$INPUT_LINE_NUMBER
__$.
_はPerlで常に使用されます。 Rubyでは、「魔法の」面を避けるために以下の方法を使用することをお勧めします。
_require 'english'
puts $INPUT_LINE_NUMBER
_
フィールドに埋め込まれた行末を処理する必要がある場合は、わずかな変更で簡単に処理できます。改行が埋め込まれた行を含む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
_
with_index
_Enumeratorの with_index(1)
を使用すると、CSVがブロックに渡す回数を簡単に追跡でき、_$.
_を使用して効果的にシミュレートしますが、余分な行を読み込むときにCSVラインエンドに対処するために必要なもの:
_require 'csv'
CSV.foreach('test.csv', headers: true).with_index(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"
_
代替ソリューションは次のとおりです。
options = {:encoding => 'UTF-8', :skip_blanks => true}
CSV.foreach("data.csv", options).with_index do |row, i|
puts i
end
クリーンではなく、シンプルなソリューション
options = {:encoding => 'UTF-8', :skip_blanks => true}
i = 0
CSV.foreach("data.csv", options) do | row |
puts i
i += 1
end