以下のスクリプトはCSVファイルを読み込み、条件に合致する特定の行のデータだけをタブ区切りファイルとして出力するrubyのスクリプトです。
入力データを編集して、出力データを作成する場合、ある項目が特定の値をもつレコードだけを出力する場合があります。リレーショナル・データベース(relational data base)でいうと、選択(selection)に相当するものですが、このような場合、if文を利用することになります。
if文は、「if (条件) then 条件に該当する場合に行う処理 end」という形式で記述します。通常、「条件に該当する場合に行う処理」は、わかりやすくするため、改行して記述することが多いため、「end」は改行して、「if」と同じカラム(桁)にそろえます。また、if文を1行で記入する場合は、条件の後に「then」を記述する必要がありますが、上記のように改行する場合は、「then」をつける必要はありません。
条件がいくつかに別れていて、それぞれ別々の処理を行う場合は、以下のように「else」や「elsif」を使って記述します。なお、「else」に該当する処理がなければ、省略します。また、「elsif」はいくつでも追加することが可能です。「end」は途中に「else」や「elsif」がいくつ入っても、最後に1つだけつけます。
if (条件A) then 条件Aに該当する場合に行う処理 end
if (条件A) then 条件Aに該当する場合に行う処理 else 条件A以外に該当する場合に行う処理 end
if (条件A) then 条件Aに該当する場合に行う処理 elsif (条件B) then 条件A以外で条件Bに該当する場合に行う処理 end
if (条件A) then 条件Aに該当する場合に行う処理 elsif (条件B) then 条件A以外で条件Bに該当する場合に行う処理 else 条件Aにも条件Bにも該当しない場合に行う処理 end
「elsif」は、「elsif」で指定している条件の他に、それ以前に記述している「if」や「elsif」以外の条件であることが前提になっていますので、記述する順序については、よく考えておくことが必要です。さまざまなパターンを想定しておかないと、いくつも条件があるのに、すべてのデータが最初の条件だけに該当してしまうということが起きることがあります。
それぞれの条件がandやorで接続されて複合的になる場合は、それぞれ個別の条件ごとに「()」(かっこ)を使うだけでなく、条件全体にも「()」をつけます。Rubyでは、and条件を「&&」、or条件を「||」(一般的な日本語109キーボードでは、[Back Space]キーの左隣、「\」のあるキー)で指定します。ただし、複合条件をわかりやすく記述するため、2行以上にする場合は、「&&」や「||」は前の行に記述します(後の行に記述すると「Syntax error」になるので注意してください)。
また、条件そのものは、一般的に比較演算子を使って記述します。比較演算子とは、2つの項目の大小関係を規定するための記号です。Rubyでは、Perlのように変数が文字列か数値かによって、比較演算子を変える必要はありません。記述方法は、比較演算子の左側に変数、右側に変数または定数を記述します。定数は、文字列の場合、「""」(ダブルクォーテーション)でかこみ、数値の場合はそのまま記述します。それぞれの場合を表にまとめると以下のようになります。
内容 | 比較演算子 | 使用例 | 備 考 |
等しい | == |
$a == $b |
$a は $b に等しい |
等しくない | != |
$a != $b |
$a は $b に等しくない |
大きい | > |
$a > $b |
$a は $b より大きい |
小さい | < |
$a < $b |
$a は $b より小さい |
以上 | >= |
$a >= $b |
$a は $b 以上である |
以下 | <= |
$a <= $b |
$a は $b 以下である |
内容 | 比較演算子 | 使用例 | 備 考 |
等しい | == |
$a == "abc" $a == 0 |
$a は "abc" に等しい $a は 0 に等しい |
等しくない | != |
$a != "abc" $a != 0 |
$a は"abc"に等しくない $a は 0 に等しくない |
大きい | > |
$a > "abc" $a > 0 |
$a は "abc" より大きい $a は 0 より大きい |
小さい | < |
$a < "abc" $a < 0 |
$a は "abc" より小さい $a は 0 より小さい |
以上 | >= |
$a >= "abc" $a >= 0 |
$a は "abc" 以上である $a は 0 以上である |
以下 | <= |
$a <= "abc" $a <= 0 |
$a は "abc" 以下である $a は 0 以下である |
具体的なスクリプトとサンプルの入力データをつけるので、それぞれの場合(#から次の#までの間)を1つ1つコピーし、実行してください。結果は、出力データで示したようになるはずです。
# inout3.rb # 内容 : 基本プログラム(if文で条件指定した場合) # Copyright (c) 2002-2015 Mitsuo Minagawa, All rights reserved. # (minagawa@fb3.so-net.ne.jp) # 使用方法 : c:\>ruby inout3.rb # #if文で条件が1つの場合 # 入力ファイル in1_file = open("input.txt","r") # 出力ファイル out1_file = open("output1.txt","w") # 主処理 while (line1 = in1_file.gets) line1.chomp! in1 = line1.split(",",-1) if (in1[0] == "AAAA") out1 = in1.join("\t") out1_file.print out1,"\n" end end # ファイルのクローズ in1_file.close out1_file.close #if文でelseをつける場合 # 入力ファイル in1_file = open("input.txt","r") # 出力ファイル out1_file = open("output2.txt","w") # 主処理 while (line1 = in1_file.gets) line1.chomp! in1 = line1.split(",",-1) if (in1[0] == "AAAA") out1 = in1.join("\t") out1_file.print out1,"\n" else in1[1] = "9999" out1 = in1.join("\t") out1_file.print out1,"\n" end end # ファイルのクローズ in1_file.close out1_file.close #if文でelsifをつける場合 # 入力ファイル in1_file = open("input.txt","r") # 出力ファイル out1_file = open("output3.txt","w") # 主処理 while (line1 = in1_file.gets) line1.chomp! in1 = line1.split(",",-1) if (in1[0] == "AAAA") out1 = in1.join("\t") out1_file.print out1,"\n" elsif (in1[0] == "BBBB") in1[1] = "1111" out1 = in1.join("\t") out1_file.print out1,"\n" end end # ファイルのクローズ in1_file.close out1_file.close #if文でelsifとelseをつける場合 # 入力ファイル in1_file = open("input.txt","r") # 出力ファイル out1_file = open("output4.txt","w") # 主処理 while (line1 = in1_file.gets) line1.chomp! in1 = line1.split(",",-1) if (in1[0] == "AAAA") out1 = in1.join("\t") out1_file.print out1,"\n" elsif (in1[0] == "BBBB") in1[1] = "1111" out1 = in1.join("\t") out1_file.print out1,"\n" else in1[1] = "8888" out1 = in1.join("\t") out1_file.print out1,"\n" end end # ファイルのクローズ in1_file.close out1_file.close #if文でandやorを使う場合 # 入力ファイル in1_file = open("input.txt","r") # 出力ファイル out1_file = open("output5.txt","w") # 主処理 while (line1 = in1_file.gets) line1.chomp! in1 = line1.split(",",-1) if ((in1[0] == "AAAA") && (in1[1] == 1111)) out1 = in1.join("\t") out1_file.print out1,"\n" else in1[1] = "9999" out1 = in1.join("\t") out1_file.print out1,"\n" end end # ファイルのクローズ in1_file.close out1_file.close
AAAA,1111,1000,2000,3000 AAAA,2222,1000,2000,3000 AAAA,1111,1000,2000,3000 AAAA,3333,1000,2000,3000 BBBB,1111,1000,2000,3000 BBBB,2222,1000,2000,3000 BBBB,3333,1000,2000,3000 CCCC,1111,1000,2000,3000 CCCC,2222,1000,2000,3000 CCCC,3333,1000,2000,3000
AAAA 1111 1000 2000 3000 AAAA 2222 1000 2000 3000 AAAA 1111 1000 2000 3000 AAAA 3333 1000 2000 3000
AAAA 1111 1000 2000 3000 AAAA 2222 1000 2000 3000 AAAA 1111 1000 2000 3000 AAAA 3333 1000 2000 3000 BBBB 9999 1000 2000 3000 BBBB 9999 1000 2000 3000 BBBB 9999 1000 2000 3000 CCCC 9999 1000 2000 3000 CCCC 9999 1000 2000 3000 CCCC 9999 1000 2000 3000
AAAA 1111 1000 2000 3000 AAAA 2222 1000 2000 3000 AAAA 1111 1000 2000 3000 AAAA 3333 1000 2000 3000 BBBB 1111 1000 2000 3000 BBBB 1111 1000 2000 3000 BBBB 1111 1000 2000 3000
AAAA 1111 1000 2000 3000 AAAA 2222 1000 2000 3000 AAAA 1111 1000 2000 3000 AAAA 3333 1000 2000 3000 BBBB 1111 1000 2000 3000 BBBB 1111 1000 2000 3000 BBBB 1111 1000 2000 3000 CCCC 8888 1000 2000 3000 CCCC 8888 1000 2000 3000 CCCC 8888 1000 2000 3000
AAAA 1111 1000 2000 3000 AAAA 9999 1000 2000 3000 AAAA 1111 1000 2000 3000 AAAA 9999 1000 2000 3000 BBBB 9999 1000 2000 3000 BBBB 9999 1000 2000 3000 BBBB 9999 1000 2000 3000 CCCC 9999 1000 2000 3000 CCCC 9999 1000 2000 3000 CCCC 9999 1000 2000 3000