■Windows版Rubyの細道・けもの道

■ナビゲータ

[南北館(最初のメニュー)]

  1. [Windows版Rubyの細道・けもの道]
    1. [1.準備編]
    2. [2.基本編]
      1. [2-1.基本処理]
        1. [2-1-1.スクリプトの基本形]
        2. [2-1-2.必要な項目だけを出力する]
        3. [2-1-3.条件をつけて出力する]
        4. [2-1-4.スクリプトと入出力ファイルを異なるフォルダに入れる]
        5. [2-1-5.スクリプトの中で漢字を使う]
      2. [2-2.キーブレイク処理]
      3. [2-3.マッチング(照合)処理]
      4. [2-4.ソート(並べ替え)処理]
      5. [2-5.パターンマッチ処理]
    3. [3.応用編]
    4. [スクリプトと入力データのサンプル]
Perlではどう処理する?
同じことをPerlではこうしています。

2.基本編

2-1.基本処理

2-1-3.条件をつけて出力する

以下のスクリプトは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つだけつけます。

1.条件Aの場合だけに特定の処理を行う場合は、以下のように記述します。
    if (条件A) then
     条件Aに該当する場合に行う処理   
    end
    
2.条件Aか条件A以外の二者択一の場合は、「else」を使って、以下のように記述します。
    if (条件A) then 
        条件Aに該当する場合に行う処理
    else 
        条件A以外に該当する場合に行う処理   
    end
    
3.条件Aかそれ以外の条件Bを指定する場合は、「elsif」を使って、以下のように記述します。
    if    (条件A) then 
           条件Aに該当する場合に行う処理
    elsif (条件B) then 
           条件A以外で条件Bに該当する場合に行う処理   
    end
    
4.「if」や「elsif」で指定したすべての条件以外は、最後に「else」を使って、以下のように記述します。
    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
    
【出力データ(output1.txt)】
AAAA    1111    1000    2000    3000 
AAAA    2222    1000    2000    3000 
AAAA    1111    1000    2000    3000 
AAAA    3333    1000    2000    3000 
    
【出力データ(output2.txt)】
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 
    
【出力データ(output3.txt)】
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 
    
【出力データ(output4.txt)】
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 
    
【出力データ(output5.txt)】
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 
    



Copyright (c) 2004-2015 Mitsuo Minagawa, All rights reserved.