タブ区切り(TSV,Tab-Separated Values)テキストを読んでCSV(Comma-Separated Values)にして出力する。簡易版であり,元のデータにコンマが含まれているとまずい。1行目の -w
はwarningをonにするオプションであるが,/usr/bin/env
と組み合わせると,環境によってはうまくいかない。その場合は -w
を取るか,あるいは #! /usr/bin/ruby -w
のようにフルパスにする。2行目は省略可。
#! /usr/bin/env ruby -w # coding: utf-8 while line = gets puts line.split("\t").join(",") end
タブ("\t"
)を区切りとして配列に分割し,それを再びコンマ(","
)で結合している。実は,line
には改行も付いているので,最後の要素には改行が付く。puts
は通常は改行付きで出力するが,すでに改行があれば改行を繰り返さないので,これでうまくいく。個々の要素を操作する必要がある場合には,line
を chomp
して改行を取り除いてから操作する。したがって,ループの中は次のようにしても同じである。
puts line.chomp.split("\t").join(",")
個々の要素の前後の空白や改行を削除するには strip
を使う:
puts line.split("\t").each { |x| x.strip! }.join(",")
あるいはもっとコンサイスに次のようにもできる:
puts line.split("\t").map(&:strip).join(",")
ところでExcelはBOM(EF BB BFの3バイト)が頭に付いていないとUTF-8だと認識しない(SJISだと思われてしまう)。BOMを付けるには while ...
の前に
print "\xef\xbb\xbf"
を入れる。
以上は標準入力から読み込んだが,ファイル名を指定する場合は次のようにする:
File.open("test.txt", "r") do |f| while line = f.gets puts line.split("\t").join(",") end end
上と逆に,CSVを読んでTSVを出力するには,上と同様にして "\t"
と ","
を逆にすればいいが,CSVはデータ作法にも書いたように少しややこしいルールがあり,それに従って読み書きするために,ここではRubyのCSVクラスを使う。例えばCSVファイルをタブ区切りテキスト(TSV)に直すには次のようにする:
#! /usr/bin/env ruby -w require 'csv' CSV(STDIN).each do |row| puts row.join("\t") end
STDIN
は標準入力を表す定数である。変数 $stdin
も初期値として STDIN
が入っているので,こちらを使ってもよい。
ファイル名を指定する場合は次のようにする:
CSV.foreach("test.csv") do |row|
BOM付きUTF-8の場合は,最初の要素にBOMが付いたままになる(見えないが文字数を調べれば1文字分増える)。数値の場合は文字列として読まれるので "123"
を読んだつもりで "123".to_f
として数値 123 が得られると思ったら,"[BOM]123".to_f
だったので 0 になるといった事故がありうる。BOMのありなしにかかわらずBOMを取り払って読むには次のようにする:
File.open("test.csv", "r:BOM|UTF-8") do |f| CSV(f).each do |row| puts row.join("\t") end end
または
CSV.open("test.csv", "r:BOM|UTF-8").each do |row| puts row.join("\t") end