「3-3-2.複数のファイルをまとめて、1つのファイルにする」とは逆に1つの入力ファイルから複数の出力ファイルに振り分ける方法について解説します。ここでは、日本郵政公社(2003年3月までは郵政事業庁)が提供している郵便番号データを都道府県別に出力する方法を例にとって説明します。郵便番号データは下記のサイトにあるので参照してください。
http://www.post.japanpost.jp/zipcode/
入力データの1項目目はJISで定められた都道府県コード(2バイト)と市区町村コード(3バイト)の2つを組み合わせた5バイトのデータになっています。そこで、入力データの1項目目から先頭2バイトを取り、そのデータに基づいて、出力ファイルを分けて出力します。
具体的には、【スクリプト】その1を見ていただければわかるように、Rubyでは、ioクラスのオブジェクトに変数を指定することはできませんが、openメソッドの引数で指定するファイル名には変数が指定できますので、入力データの1つとして、県別の出力ファイル名を指定したファイルをあらかじめ用意しておくことで、スクリプト自体がすっきりとした形になります。openメソッドを定数で指定した場合、どのようになるかを【スクリプト】その2で提示していますので、比較すると、どのくらい簡潔になるかがわかるでしょう。入出力ファイルが増えてきた場合、このように変数で指定することでスクリプトがすっきりと表示できるようになります。
なお、入力データはキー順に並べ替えてあることが前提となっています。Rubyを利用して並べ替えを行う場合については、[2-4.ソート(並べ替え)処理]を参照してください。
01101,"060 ","0600000","ホッカイドウ","サッポロシチュウオウク","イカニケイサイガナイバアイ","北海道","札幌市中央区","以下に掲載がない場合",0,0,0,0,0,0 01101,"064 ","0640941","ホッカイドウ","サッポロシチュウオウク","アサヒガオカ","北海道","札幌市中央区","旭ケ丘",0,0,1,0,0,0
01,01HOKKAIDO.CSV 02,02AOMORI.CSV 03,03IWATE.CSV 04,04MIYAGI.CSV 05,05AKITA.CSV 06,06YAMAGATA.CSV 07,07FUKUSHIMA.CSV 08,08IBARAKI.CSV 09,09TOCHIGI.CSV 10,10GUMMA.CSV 11,11SAITAMA.CSV 12,12CHIBA.CSV 13,13TOKYO.CSV 14,14KANAGAWA.CSV 15,15NIIGATA.CSV 16,16TOYAMA.CSV 17,17ISHIKAWA.CSV 18,18FUKUI.CSV 19,19YAMANASHI.CSV 20,20NAGANO.CSV 21,21GIFU.CSV 22,22SHIZUOKA.CSV 23,23AICHI.CSV 24,24MIE.CSV 25,25SHIGA.CSV 26,26KYOTO.CSV 27,27OSAKA.CSV 28,28HYOGO.CSV 29,29NARA.CSV 30,30WAKAYAMA.CSV 31,31TOTTORI.CSV 32,32SHIMANE.CSV 33,33OKAYAMA.CSV 34,34HIROSHIMA.CSV 35,35YAMAGUCHI.CSV 36,36TOKUSHIMA.CSV 37,37KAGAWA.CSV 38,38EHIME.CSV 39,39KOCHI.CSV 40,40FUKUOKA.CSV 41,41SAGA.CSV 42,42NAGASAKI.CSV 43,43KUMAMOTO.CSV 44,44OITA.CSV 45,45MIYAZAKI.CSV 46,46KAGOSHIMA.CSV 47,47OKINAWA.CSV
# ken1.rb # 内容 : 郵便番号データを県別に分割するスクリプト # Copyright (c) 2002-2015 Mitsuo Minagawa, All rights reserved. # (minagawa@fb3.so-net.ne.jp) # 使用方法 : c:\>ruby ken1.rb # # 入力ファイル(郵便番号データ) in1_file = open("ken_all.csv","r") # 入力ファイル(都道府県名データ) in2_file = open("ken.txt","r") in2_ctr = 0 #入力件数(都道府県名データ) sv_ken = 0 #都道府県コードの保存コード w_file_nm = Array.new() #都道府県名の配列 # 都道府県名のファイルを読み込む while (line2 = in2_file.gets) line2.chomp! in2 = line2.split(",",-1) in2_ctr += 1 w_file_nm[in2_ctr] = in2[1] end # 主処理 while (line1 = in1_file.gets) line1.chomp! # CSV形式のファイルを配列に格納する in1 = (line1 + ',') .scan(/"([^"\\]*(?:\\.[^"\\]*)*)",|([^,]*),/) .collect{|x,y| y || x.gsub(/\\(.)/, '\1')} w_ken = in1[0].slice(0,2).to_i if (w_ken != sv_ken) w_file = w_file_nm[w_ken] out1_file = open(w_file,"w") end # 入力キーを保存 sv_ken = w_ken # 都道府県別のファイルを出力 out1_file.print line1,"\n" end # ファイルのクローズ in1_file.close
# ken2.rb # 内容 : 郵便番号データを県別に分割するスクリプト # Copyright (c) 2002-2015 Mitsuo Minagawa, All rights reserved. # (minagawa@fb3.so-net.ne.jp) # 使用方法 : c:\>ruby ken2.rb # # 入力ファイル in1_file = open("ken_all.csv","r") # 出力ファイル out01_file = open("01HOKKAIDO.CSV","w") out02_file = open("02AOMORI.CSV","w") out03_file = open("03IWATE.CSV","w") out04_file = open("04MIYAGI.CSV","w") out05_file = open("05AKITA.CSV","w") out06_file = open("06YAMAGATA.CSV","w") out07_file = open("07FUKUSHIMA.CSV","w") out08_file = open("08IBARAKI.CSV","w") out09_file = open("09TOCHIGI.CSV","w") out10_file = open("10GUMMA.CSV","w") out11_file = open("11SAITAMA.CSV","w") out12_file = open("12CHIBA.CSV","w") out13_file = open("13TOKYO.CSV","w") out14_file = open("14KANAGAWA.CSV","w") out15_file = open("15NIIGATA.CSV","w") out16_file = open("16TOYAMA.CSV","w") out17_file = open("17ISHIKAWA.CSV","w") out18_file = open("18FUKUI.CSV","w") out19_file = open("19YAMANASHI.CSV","w") out20_file = open("20NAGANO.CSV","w") out21_file = open("21GIFU.CSV","w") out22_file = open("22SHIZUOKA.CSV","w") out23_file = open("23AICHI.CSV","w") out24_file = open("24MIE.CSV","w") out25_file = open("25SHIGA.CSV","w") out26_file = open("26KYOTO.CSV","w") out27_file = open("27OSAKA.CSV","w") out28_file = open("28HYOGO.CSV","w") out29_file = open("29NARA.CSV","w") out30_file = open("30WAKAYAMA.CSV","w") out31_file = open("31TOTTORI.CSV","w") out32_file = open("32SHIMANE.CSV","w") out33_file = open("33OKAYAMA.CSV","w") out34_file = open("34HIROSHIMA.CSV","w") out35_file = open("35YAMAGUCHI.CSV","w") out36_file = open("36TOKUSHIMA.CSV","w") out37_file = open("37KAGAWA.CSV","w") out38_file = open("38EHIME.CSV","w") out39_file = open("39KOCHI.CSV","w") out40_file = open("40FUKUOKA.CSV","w") out41_file = open("41SAGA.CSV","w") out42_file = open("42NAGASAKI.CSV","w") out43_file = open("43KUMAMOTO.CSV","w") out44_file = open("44OITA.CSV","w") out45_file = open("45MIYAZAKI.CSV","w") out46_file = open("46KAGOSHIMA.CSV","w") out47_file = open("47OKINAWA.CSV","w") # 主処理 while (line1 = in1_file.gets) line1.chomp! # CSV形式のファイルを配列に格納する in1 = (line1 + ',') .scan(/"([^"\\]*(?:\\.[^"\\]*)*)",|([^,]*),/) .collect{|x,y| y || x.gsub(/\\(.)/, '\1')} w_ken = in1[0].slice(0,2) case w_ken when "01" out01_file.print line1,"\n" when "02" out02_file.print line1,"\n" when "03" out03_file.print line1,"\n" when "04" out04_file.print line1,"\n" when "05" out05_file.print line1,"\n" when "06" out06_file.print line1,"\n" when "07" out07_file.print line1,"\n" when "08" out08_file.print line1,"\n" when "09" out09_file.print line1,"\n" when "10" out10_file.print line1,"\n" when "11" out11_file.print line1,"\n" when "12" out12_file.print line1,"\n" when "13" out13_file.print line1,"\n" when "14" out14_file.print line1,"\n" when "15" out15_file.print line1,"\n" when "16" out16_file.print line1,"\n" when "17" out17_file.print line1,"\n" when "18" out18_file.print line1,"\n" when "19" out19_file.print line1,"\n" when "20" out20_file.print line1,"\n" when "21" out21_file.print line1,"\n" when "22" out22_file.print line1,"\n" when "23" out23_file.print line1,"\n" when "24" out24_file.print line1,"\n" when "25" out25_file.print line1,"\n" when "26" out26_file.print line1,"\n" when "27" out27_file.print line1,"\n" when "28" out28_file.print line1,"\n" when "29" out29_file.print line1,"\n" when "30" out30_file.print line1,"\n" when "31" out31_file.print line1,"\n" when "32" out32_file.print line1,"\n" when "33" out33_file.print line1,"\n" when "34" out34_file.print line1,"\n" when "35" out35_file.print line1,"\n" when "36" out36_file.print line1,"\n" when "37" out37_file.print line1,"\n" when "38" out38_file.print line1,"\n" when "39" out39_file.print line1,"\n" when "40" out40_file.print line1,"\n" when "41" out41_file.print line1,"\n" when "42" out42_file.print line1,"\n" when "43" out43_file.print line1,"\n" when "44" out44_file.print line1,"\n" when "45" out45_file.print line1,"\n" when "46" out46_file.print line1,"\n" when "47" out47_file.print line1,"\n" end end # ファイルのクローズ in1_file.close out01_file.close out02_file.close out03_file.close out04_file.close out05_file.close out06_file.close out07_file.close out08_file.close out09_file.close out10_file.close out11_file.close out12_file.close out13_file.close out14_file.close out15_file.close out16_file.close out17_file.close out18_file.close out19_file.close out20_file.close out21_file.close out22_file.close out23_file.close out24_file.close out25_file.close out26_file.close out27_file.close out28_file.close out29_file.close out30_file.close out31_file.close out32_file.close out33_file.close out34_file.close out35_file.close out36_file.close out37_file.close out38_file.close out39_file.close out40_file.close out41_file.close out42_file.close out43_file.close out44_file.close out45_file.close out46_file.close out47_file.close
入力データ(県別の出力ファイル名)のサンプルはこちらにあります。