#はじめに
この記事では、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クラスは最初はちょっとよくわからなかったんですが、この記事書きながら頭の中整理できたので、これからもどんどん使っていこうと思います。