LoginSignup
0
0

More than 3 years have passed since last update.

Rubyで、TSVファイルからCSVファイル(BOM付き)への変換

Last updated at Posted at 2020-09-29

はじめに

Rubyにおけるタブ区切りのファイル(TSVファイル)から、BOM付きのCSVファイルへの変換方法です。

目次

0.完成コード
1.BOMを付けたCSVファイルの作成
2.TSVファイル内データの読み込み
3.CSVに1行づつ読んでは書いていく
4.プログラムを実行

0.完成コード

tsv_to_csv.rb

require 'csv'

# CSVファイルを作成し、bomを付ける。
File.write("meibo.csv", "\uFEFF")

# 'meibo2.txt'の情報を1行毎に読み込み、splitで配列にして、CSVファイルに1行ずつ入れていく。
CSV.open("meibo.csv", "a", force_quotes: true ) do |meibocsv|
  File.foreach('meibo.txt') do |student|
    meibocsv << student.chomp.split("\t", -1)
  end
end

1.BOMを付けたCSVファイルの作成

BOM(Byte order mark)は、Unicodeの符号化形式で符号化したテキストの先頭に着ける数バイトのデータのことを言います。
ExcelはCSVファイルを開くときデフォルトでShift-JISで開こうとするため、UTF-8では文字化けを起こしてしまいます。その対処法として、UTF-8で出力する際にBOMを付けてあげることでExcelにUTF-8で書かれていると認識させて、文字化けを防ぐことができます。
以下のようにしてBOMを付けてます。

File.write("meibo.csv", "\uFEFF")

2.TSVファイル内データの読み込み

読み込むTSVファイルは以下。

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

タブ区切り形式のデータが書かれたmeibo.txtを読み込みますが、1行読み込んでは1行書き込むという手法をとりたいです。タブ区切りデータ1行をsplitで配列に変換した後、そのままCSVファイルに書き込んでいくようにします。

File.foreach('meibo.txt') do |student|
  CSVファイル) << student.chomp.split("\t", -1)
end

3.CSVに1行づつ読んでは書いていく

上のコードをCSV.openで囲えば、1行読み書きができます。
基本的に、タブ区切りファイルから、CSVファイルへ移すという場合は、1行ずつ処理していきます。なぜならば、仮に1000万行のような膨大なデータであっても、メモリがオーバーすることを防ぐためです。

CSV.open("meibo.csv", "a", force_quotes: true ) do |meibo_csv|
  File.foreach('meibo.txt') do |student|
    meibo_csv << student.chomp.split("\t", -1)
  end
end

因みにsplitの第2引数(limit)に、-1を渡しています。
この第2引数の値はデフォルトでは0になっており、配列末尾の空文字列を取り除いてしまいます。
これではTSVに空のフィールドがあったときにうまく行きません。-1を渡してあげることで、解決することができます。

4.プログラムを実行

% ruby tsv_to_csv.rb 

データが書き込まれたCSVファイルが生成される。

meibo.csv
"john","m","18"
"paul","m","20"
"alice","f","15"
"dabid","m","17"
"jasmin","f","17"

カンマ区切りのCSVファイルに正しく変換されました。

0
0
0

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
0
0