LoginSignup
2
2

More than 3 years have passed since last update.

RubyでのTSVファイルとCSVファイルの取り扱い方

Last updated at Posted at 2020-10-15

はじめに

この記事では、Rubyにおいて、TSVファイルやCSVファイルを扱う上での基礎知識を、myメモ的な感じでまとめました。TSV,CSV以前に、Fileクラスについても一緒に確認できればと思います。

TSVファイルとは

タブ区切りでデータが格納されたファイル

CSVファイルとは

コンマ( , )区切りでデータが格納されたファイル

本記事では以下のTSVファイルを例にあつかいます

# meibo.txt
john    m   18
paul    m   20
alice   f   15
dabid   m   17
jasmin  f   17

Fileクラスについて

ファイルを開く

#書き方1
File.open("meibo.txt") do |file|
  処理
end

#書き方2
file = File.open("meibo.txt")
  処理
file.close

書き方1はファイルを開いても勝手に閉じてくれますが、書き方2ではcloseメソッドをしないとファイル開きっぱなしです。なので、書き方1の方が個人的には好きです。

File.open("meibo.txt") do |file|
  puts.file
end

例えば、上記のようにすると、以下のようなFileオブジェクトの標準出力を得ます。

#<File:0x00007fba4497ea68>

ファイルを読み込む

開いたファイルは、読み込んだりします。

File.open("meibo.txt") do |file|
  p file.read
end

すると、以下のような標準出力になります。

"john\tm\t18\npaul\tm\t20\nalice\tf\t15\ndabid\tm\t17\njasmin\tf\t17\n"

いきなり読み込んでも大丈夫です。

file = File.read("meibo.txt")
p file

#=>
"john\tm\t18\npaul\tm\t20\nalice\tf\t15\ndabid\tm\t17\njasmin\tf\t17\n"

一行ずつ読みたい場合、以下のように、一度ファイルを開いて、その処理の部分で、一行ずつ読ませて、好きな処理を入れます。

File.open("meibo.txt") do |file|
  file.each do |line|
    処理
  end
end

#例えば

File.open("meibo.txt") do |file|
  file.each do |line|
    p "#{line.chomp}\tfoo"
  end
end

#=>
"john\tm\t18\tfoo"
"paul\tm\t20\tfoo"
"alice\tf\t15\tfoo"
"dabid\tm\t17\tfoo"
"jasmin\tf\t17\tfoo"

以上がFileクラスでの扱い方ですが、出力が数珠つなぎの文字列になっているので、少々扱いづらいかと思います。そこで、CSVクラスを使用することで、データを扱いやすくすることができます。

CSVクラスについて

本来CSVファイルを扱うためのクラスだと思いますが、col_sepオプション(指定した文字列で区切ってくれる)を使うとTSVファイルもCVSクラスで扱えます。CSVクラスを使用するときは行頭にrequire "csv"を付けます。

require "csv"

#openメソッドを使うなら
CSV.open("meibo.txt", col_sep: "\t") do |tsv|
  p tsv.read
end

#openメソッドを使わないなら
tsv = CSV.read("meibo.txt", col_sep: "\t")
p tsv

#=>
[["john", "m", "18"], ["paul", "m", "20"], ["alice", "f", "15"], ["dabid", "m", "17"], ["jasmin", "f", "17"]]

CSVメソッドを用いて読み込むと、出力結果は配列に入れて返されます。
こうすることで、データとして扱いやすくなります。
一行ずつ読ませたいなら以下のforeachメソッドを使います。

require "csv"

CSV.foreach("meibo.txt", col_sep: "\t") do |line|
  処理
end

#例えば
CSV.foreach("meibo.txt", col_sep: "\t") do |line|
  p line
end

#=>
["john", "m", "18"]
["paul", "m", "20"]
["alice", "f", "15"]
["dabid", "m", "17"]
["jasmin", "f", "17"]

こうすることで、各行ごとに配列に対して処理を行うことができます。

ちなみに、もちろんですが、新たにCSVファイルを開いて、そこに書き込むこともできます。

require "csv"

CSV.open("meibo.csv","w") do |line| #"w"は書き込みモード
 line << ["michel","m",16]
end

# meibo.csv
michel,m,16

TSVをCSVに変換

最後に、これまでにご紹介した構文を使って、TSVファイルをCSVファイルに変換できます。
いきなり結論ですが、以下です。

require "csv"

CSV.open('meibo.csv', 'w') do |csv|
  CSV.foreach("meibo.txt", col_sep: "\t") do |line|
   csv << line
 end
end

まず、書き込みモードでCSVファイルを用意します。そのCSVファイルに、foreachでTSVファイルの各行を一行ずつCSVに格納して行くという、流れです。
CSVからTSVについてもこの逆を行えばOKです。

さいごに

Fileクラスは最初はちょっとよくわからなかったんですが、この記事書きながら頭の中整理できたので、これからもどんどん使っていこうと思います。

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2