Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
177
Help us understand the problem. What is going on with this article?
@shizuma

Ruby CSVを扱うためのメモ

More than 5 years have passed since last update.

Rubyでcsvを扱うときにパッと使えるようにメモを残しておきます。
やることは以下です。

  • CSVファイルからデータを読み込むこと ( CSV.read )
  • 読み込んだCSVデータをtxtファイルに出力すること ( File.open、file.write )

おまけ

  • CSV.foreachでもCSVから読み込み
  • CSV.generateでCSVで出力する

CSV.read

member.csvというcsvファイルを読み込んで、intro.txtとファイルに出力するサンプルです。

create_intro.rb
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."
member.csv
id,name,club,age
1,shizuma,baseball,22
2,qiita,soccer,33
3,taro,tennis,16

以下のファイルが出力されるファイルです。

intro.txt
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."

出力は以下のような感じ。

intro.csv
1,shizuma,baseballクラブ,22歳
2,qiita,soccerクラブ,33歳
3,taro,tennisクラブ,16歳

これだけあれば色々出来そうですね!

177
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
shizuma
web&DeepLearningエンジニア。 ACES.inc←東京大学大学院/東京←鹿児島/blog https://blog.seishin55.com ; Qiita https://qiita.com/shizuma ; note https://note.mu/seishin55
aces
ACES(エーシーズ)は、 画像認識を中心としたAIアルゴリズムの力で、リアル産業のDX(デジタルトランスフォーメーション)を推進し、シンプルな社会を実現する会社です。ヒトの働き方をデジタルの力で 自動化・効率化することで、誰もが生き生きと 生きられる社会を実現していきます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
177
Help us understand the problem. What is going on with this article?