1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rubyでのファイル形式の変換まとめ(TSV, CSV, JSON)

Last updated at Posted at 2020-12-05

###ファイル形式の種類
データには様々な形式がありますが、入力のファイル形式と違うファイル形式で出力したいことがあると思います。今回は、以下の3つのファイル形式を扱い、Ruby上で変換する方法をまとめました。

①TSV (Tab Separated Values)・・・各項目の間がタブで区切られたテキストデータ。拡張子はtxtかtsv。

people.tsv
alice  f  20
bob    m  19
conner m  34
david  m  23
elena  f  24

②CSV (Comma Separated Values)・・・各項目の間がカンマ(,)で区切られたテキストデータ。拡張子はtxtかcsv。

people.csv
"alice","f",20
"bob","m",19
"conner","m",34
"david","m",23
"elena","f",24

③JSON (JavaScript Object Notation)・・・ Javascriptで組み込まれているオブジェクトというデータ記述をベースとしたデータ。Rubyでいうハッシュのようなキーと値を持つ。拡張子はtxtかjson。

people.json
[{"name":"alice","gender":"f","age":"20"},
 {"name":"bob","gender":"m","age":"19"},
 {"name":"conner","gender":"m","age":"34"},
 {"name":"david","gender":"m","age":"23"},
 {"name":"elena","gender":"f","age":"24"}]

これらを互いに変換していきたいと思います。

##TSVの変換

###TSV→CSV

require 'csv'

CSV.open('people.csv','w', :force_quotes => true) do |people|
  File.foreach("people.txt") {|line| people <<  line.chomp.split(/\t/)}
end

rubyでcsvを使用するには、csvモジュールを1行目で読み込む必要があります。
CSVの書き込みは、CSV.open('新しいファイル名', 'w')とします。
:force_quotesは、全ての文字列をダブルクオーテーションでくくるようににするオプションです。

foreachメソッドは、ブロックと一緒に使うことで、引数にとったファイルを1行ごとに文字列として抽出することができます。ここでは、people.txtが行ごとにlineという変数に置き換わり、ブロック内の処理が行われます。lineは文字列なので、chompで改行を削除、split(/\t/)でタブを要素の区切りとみなして、文字列を配列に変えます。
この配列を、peopleに追加しています(<<メソッド)。peopleは、CSV.openのブロック変数で、これに配列を追加するとcsvファイルの内容を書き換えることができます。

###TSV→JSON


require 'json'

people = []

File.foreach('meibo.txt') {|line|
 cols = line.chomp.split("\t")
 people << {"name" => cols[0], "gender" => cols[1], "age" => cols[2]}
}

File.write('meibo3.json', JSON.dump(people))

rubyでjsonを使用するには、jsonモジュールを1行目で読み込みます。
最後の行に注目してください。


File.write('meibo.json', JSON.dump(people))

jsonモジュールには、rubyハッシュをjsonに変換するdumpというメソッドが含まれています。そのため、meibo.txtをrubyでハッシュ化すれば(ここではpeopleという変数に格納)、jsonとして出力することができます。


people << {"name" => cols[0], "gender" => cols[1], "age" => cols[2]}

rubyのハッシュとjsonはキーを持ちます。今回のタブ区切りファイルにはキーが含まれていないので、明示的に作成しています。

##CSVの変換

###CSV→TSV

require 'csv'

File.open('meibo.txt', 'w') do |f|
  CSV.foreach('people.csv') {|line|
      f << line.join("\t")
      f << "\n"
  }
end

CSV.foreachメソッドは、各行を配列として1行ずつ出力します。(File.foreachは文字列として出力)
joinメソッドを使って、配列の要素をタブ区切りの一つの文字列として書き込みます。

###CSV→JSON

require 'csv'
require 'json'

people = []

CSV.foreach('people.csv') {|line|
  people << {"name" => line[0], "gender" => line[1], "age" => line[2]}
}

File.write('people.json', JSON.dump(people))

##JSONの変換

###JSON→TSV

require 'json'

File.open('meibo.txt', 'w') do |f|
  File.open('meibo.json') do |json|
    people = JSON.load(json)
    people.each do |person|
      f << [person["name"], person["gender"], person["age"]].join("\t")
      f << "\n"
    end
  end
end

jsonモジュールのloadメソッドは、JSON形式の文字列を Rubyオブジェクトとして返します。ここでは、peopleという変数にそれを代入し、eachメソッドで処理することで各要素を抽出しています。

###JSON→CSV

require 'csv'
require 'json'

CSV.open('meibo.csv', 'w', :force_quotes => true) do |f|
  File.open('meibo.json') do |json|
    people = JSON.load(json)
    people.each do |person|
      f << [person["name"], person["gender"], person["age"]]
    end
  end
end

CSV.openで開いたファイル(変数f)に配列を突っ込むといい感じにcsvファイルとして扱ってくれます。
JSON.loadでファイルを開き、1要素ずつを配列化してfに加えてます。

1
4
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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?