先日 Ruby 2.0 がリリース されましたね。しばらく Ruby はレガシーな使い方しかしてないものの、キーワード引数やデフォルトUTF-8エンコーディングなど便利そうな機能も多く楽しみです。
さて、今回は 2 つの CSV ファイルを結合する手抜きのサンプルスクリプトのご紹介。ある日友人から
- Windows 環境で
- 2つの CSV ファイルを横に連結したく
- たまたまその環境で動くのが Ruby だったので Ruby で処理できるといいな (その友人は数値処理系のプログラムはガシガシ書けるけど Ruby はあまり触ったことない)
という相談を受け、ちょろっと書いてみたスクリプトが以下になります (ダウンロード)。
#!/usr/bin/ruby ######################################## #### Settings DELIM="," ######################################## #### Main Program if ARGV.size < 3 print <<-"EOH" USAGE: ruby #{$0} <IN-FILE1> <IN-FILE2> <OUT-FILE> EOH exit 1 end in1, in2, out = ARGV[0..2] in1lines = File.open(in1).read.split("\n") in2lines = File.open(in2).read.split("\n") out_io = File.open(out, "w") in1size = in1lines.size in2size = in2lines.size line_num = in1size > in2size ? in1size : in2size for n in 1..line_num in1dat = in1lines[n-1] ||= "" in2dat = in2lines[n-1] ||= "" out_io.puts in1dat + DELIM + in2dat end out_io.close
何をするかというと、以下のような 2 つの CSV ファイルがある時に、
$ cat file1.csv 1,2,3 4,5,6 7,8,9 $ cat file2.csv A,B,C D,E,F G,H,I
こんなふうに連結しますよというもの。
$ ruby join_csv.rb file1.csv file2.csv out.csv $ cat out.csv 1,2,3,A,B,C 4,5,6,D,E,F 7,8,9,G,H,I
お気づきの方はお気づきの通り 「それ paste(1) コマンドでできますやん」ということで全くその通りですw。paste コマンドだと以下の使い方で OK ですね。
$ paste -d, file1.csv file2.csv > out.csv
まあ、今回はたまたま Windows 上でやりたかったということで無意味ではなかったのかなと… (汗)
上記スクリプトは行数を圧縮したくて Ruby 特有の記法で書いてる部分もありますので、もうちょっと平易に書いたものも載せておきます。(ダウンロード)
#!/usr/bin/ruby ######################################## #### Settings DELIM="," ######################################## #### Main Program if ARGV.size < 3 print <<-"EOH" USAGE: ruby #{$0} <IN-FILE1> <IN-FILE2> <OUT-FILE> EOH exit 1 end in1 = ARGV[0] in2 = ARGV[1] out = ARGV[2] in1lines = File.open(in1).read.split("\n") in2lines = File.open(in2).read.split("\n") out_io = File.open(out, "w") in1size = in1lines.size in2size = in2lines.size if in1size > in2size line_num = in1size else line_num = in2size end for n in 1..line_num in1dat = in1lines[n-1] unless in1dat in1dat = "" end in2dat = in2lines[n-1] unless in2dat in2dat = "" end out_io.puts in1dat + DELIM + in2dat end out_io.close
"Ruby CSV 結合" でググると CSV クラス の話などは出てくるのですが、意外に今回のような要望にヒットする記事がないもんだなぁと思い、枯れ木も山のなんとやらで書いてみました。
このレベルのスクリプトはちょこちょこ書いてるものの、プログラミングに関する知識やコーディングの考え方など、ニュース追っててもピンと来ないものも多く、まだまだ時代に追いつけてないなぁと実感します。そっち方面ももっと勉強しないといけませんが、まあそのうち…。
0 件のコメント:
コメントを投稿