Rubyでcsvを扱うときにパッと使えるようにメモを残しておきます。
やることは以下です。
- CSVファイルからデータを読み込むこと ( CSV.read )
- 読み込んだCSVデータをtxtファイルに出力すること ( File.open、file.write )
おまけ
- CSV.foreachでもCSVから読み込み
- CSV.generateでCSVで出力する
CSV.read
member.csvというcsvファイルを読み込んで、intro.txtとファイルに出力するサンプルです。
require 'csv'
csv_data = CSV.read('member.csv', headers: true)
puts "start..."
File.open("intro.txt", 'w') do |file|
csv_data.each do |data|
intro_msg = "#{data["club"]}クラブ所属の#{data["age"]}歳、#{data["name"]}です。\n"
puts intro_msg
file.write(intro_msg)
end
end
puts "complete! See intro.txt."
id,name,club,age
1,shizuma,baseball,22
2,qiita,soccer,33
3,taro,tennis,16
以下のファイルが出力されるファイルです。
baseballクラブ所属の22歳、shizumaです。
soccerクラブ所属の33歳、qiitaです。
tennisクラブ所属の16歳、taroです。
解説
require 'csv'
csvライブラリを読み込みます。
csv_data = CSV.read('member.csv', headers: true)
readメソッドを使ってCSVのデータを読み込みます。
headersオプションを使うと、CSVの初めの1行はheaderとして出力の際に無視されます。今回はこのオプションを使っていますが、headerがないときはこのオプションはいりません。
ちなみに今回のheaderはcsvファイルの id,name,club,age
のことですね。
File.open("intro.txt", 'w') do |file|
csv_data.each do |data|
intro_msg = "#{data["club"]}クラブ所属の#{data["age"]}歳、#{data["name"]}です。\n"
puts intro_msg
file.write(intro_msg)
end
end
まず、 File.open
の箇所ですが、第一引数に生成したいファイル名、第二引数にオプションをいれています。今回の「w」はファイルを上書きしますが、「a」とするとファイルに追記していきます。
次に、csv_data.each
のところですがdataという変数にcsvファイルのデータが1行ずつ入ります。「,」区切りで左から0、1、2、...という番号がつきます。
追記:
intro_msg = "#{data["club"]}クラブ所属の#{data["age"]}歳、#{data["name"]}です。\n"
の箇所ですが、はじめは以下のように左からの順番で値を取得していましたが、 @scivola さんにコメントを頂き上記に変更しました。csvにheaderがある場合はheaderの値で指定出来るのですね。便利です!
intro_msg = "#{data[2]}クラブ所属の#{data[3]}歳、#{data[1]}です。\n"
参考
その他オプション等
class CSV
ついでに色々やってみた
CSV.foreach
readで一気に読み込まなくても、foreachでやれば良さ気ですね。
やってることは上記のreadのファイルと一緒です。便利。
require 'csv'
puts "start..."
File.open("intro.txt", 'w') do |file|
CSV.foreach('member.csv', headers: true) do |data|
intro_msg = "#{data["club"]}クラブ所属の#{data["age"]}歳、#{data["name"]}です。\n"
puts intro_msg
file.write(intro_msg)
end
end
puts "complete! See intro.txt."
CSV.generate
CSVで吐き出すことも出来るみたいです。読み込んだデータもCSVですが、少し加工してまたCSVで出力してみます。
require 'csv'
puts "start..."
intro_csv = CSV.generate do |csv|
CSV.foreach('member.csv', headers: true) do |data|
intro_msg = [
data["id"],
data["name"],
"#{data["club"]}クラブ",
"#{data["age"]}歳"
]
csv << intro_msg
puts intro_msg
end
end
File.open("intro.csv", 'w') do |file|
file.write(intro_csv)
end
puts "complete! See intro.csv."
出力は以下のような感じ。
1,shizuma,baseballクラブ,22歳
2,qiita,soccerクラブ,33歳
3,taro,tennisクラブ,16歳
これだけあれば色々出来そうですね!