02. 制御構文

ここは、一般的な制御構文(条件分岐、ループ文)を取り扱います。他の多くのサイトで確認可能な内容ですが、まとめておきたいと思います。なお、RubyやPythonに関しては、あまり深入りしない程度にとどめます。

--- tcsh

制御構文を書くときは、スペースを入れるようにしましょう。ほんの数行のコードでは動くコードでも、数百行以上になった時、文法解析がおかしくなることがあります。こうなると、どこが原因か区別がつかなくなり、Debugがたいへんです(経験上の話)。if($a==1)then → if ( $a == 1 ) then (それぞれにスペースを入れておく)

条件判断

$var == 1 (数値:浮動小数は扱えない)

使える演算子:==, >, >=, <, <=, != など

$var == "test" (文字列)

変数内の文字列が、特定の文字列を含んでいるかどうか、というときは

簡単なパタンであれば、grepを使わずに済みます。「keyword」を含む、という意味で書くとき、

if ( $var =~ *keyword* ) then

処理

…という具合に書きます。「*」は簡易正規表現として扱われるようです。どこまでの表記が許されるかはわかりませんが、少し細かい条件を書くときは、下記のgrep/egrepで正規表現を利用するのが好ましいと思います。

*1 *keyword* は、「"」や「'」で括ってもかまいません

echo $var | grep "keyword" >! /dev/null

if ( $status == 0 ) then

処理

…という具合に書きます。

*2 "keyword" は 'keyword' でも可。grepだと正規表現も使えます

if ( $?var ) → 変数varが定義されているなら

例えば、環境変数が定義されていなければ、特定のファイルをsourceする、とかに使います

if ( ! $?ENV ) then

source xxx

endif

条件分岐

if

        • if ( 条件 ) 処理
        • if ( 条件 ) then

処理

else

処理

endif

        • else if の書き方は「else if」

switch

        • switch ( 変数 )

case 値 :

処理

breaksw

case値:

処理

breaksw

default:

処理

endsw

        • *1 case文の最後にbreakswを入れ忘れると、次のcase文中の処理もしてしまうので注意してください

ループ

while

        • while ( 条件 )

処理

end

*1 ループ内部で、条件がfalseになるようにコーディングしてください。goto文で抜けるのはお勧めしません

foreach

        • foreach 変数名 ( リスト文字列 )

処理

end

*1 変数名には $ がつきません

*2 リスト文字列は、空白区切りされた情報を指します

            • set list = ( a b c )
            • set list = `ls *.xyz`

--- Perl

条件判断

$var == 1 (数値)

使える演算子:==, >, >=, <, <=, != など

$var eq "test" (文字列)

使える演算子:eq, ne, lt, gt, le, ge, =~, !~, cmpなど

変数内の文字列が、特定の文字列を含んでいるかどうか、というときは

$var =~ /keyword/

と書きます。keywordには正規表現が使えます。

未定義変数かどうかは

defined($var)

を使います。shellの環境変数を拾うには、

$ENV{'ENV'} #ENVは環境変数名を指定

と書きます。ハッシュ扱いされます。

条件分岐

if

        • 処理 if(条件);
        • if(条件){

処理

}elsif(条件){

処理

}else{

処理

}

三項演算子というものもありますが、ここでは扱いません。三項演算子のネストはほどほどに。

*1 Perlには標準でswitch文がありませんが、それに似たような文法はバージョン限定であるようです。「perl switch」などで検索してみてください

ループ

for

        • for($i=0; $i<10; $i++){

処理

}

        • 局所変数化してあげると、「この変数名使っていいんだっけ?」という悩みから開放されます

for(my $i=0; $i<10; $i++){

処理

}

局所変数定義であるmyとlocalは挙動が異なります。myを使う方が混乱しづらいと思いますが、詳しくは他のサイトを御覧ください。

foreach

        • foreach 展開変数名(リスト){

処理

}

        • *1 展開変数名は、$tmpなど。展開変数名は、自動的に局所化されるようです。

$ppp = 10;

@kkk = (1,2,3);

foreach $ppp(@kkk){

}

print $ppp."\n";

→ 10と表示されます(壊されていない)

while

        • while(条件){

処理

}

unless

        • unless(条件){

処理

}

--- Ruby

条件判断

var ==1 (数値)

使える演算子:==, >, >=, <, <=, != など

var == "test" (文字列)

使える演算子:==, >, >=, <, <=, != など

*1 Perlでは "==" を使わないが、Rubyでは "==" で比較します。

変数内の文字列が、特定の文字列を含んでいるかどうか、というときは

var =~ /keyword/ または

/keyword/ =~ var

と書きます。keywordには正規表現が使えます。

*1 文字列の正規表現マッチングは、変数varが「数値(Fixnum)」だとErrorになります。

未定義変数かどうかは

defined?(var)

を使います。shellの環境変数を拾うには、

ENV["ENV"] または

ENV.fetch("ENV")

と書きます。"ENV"は環境変数名を指定します。ハッシュ扱いされます。

条件分岐

if

        • 処理 if 条件
        • if 条件 then

処理

elsif 条件 then

処理

else

処理

end

*1 Rubyでは条件を()で括っても括らなくても構いません

case

        • case 変数

when 値

処理

when 値

処理

else

処理

end

*1 値のところは、1,2,3... のように、カンマで複数値書くことができます

*2 値のところは、範囲演算子を用いて 1..3 というような表記もできます

ループ

種類が多いため、一部に限定します。こちらに、もう少し細かく書いています。

for

        • for var in range do

処理

end

*1 var は、rangeを展開した数値を格納する変数名です

*2 range は、例えば「1..10」などの表記をします。rangeには、定義済み配列を置いてもいいです

array = [1,2,3]

for var in array do

処理

end

*3 varは、for文内のローカル変数として扱われないので、変数名に注意が必要です(for文自体、Rubyではfor文の外とScopeが別れないようなので、Perlのように my を定義すればいい、という話にならないため注意が必要です)

each

        • array.each do |var|

処理

end

*1 array は、配列やrangeオブジェクト(range=1..3、など)が使えます

*2 var は、配列やrangeオブジェクトを展開した値を格納する変数名です

*3 var は、ローカル変数扱いされるため、その外側で同名の変数があったとしても、破壊されません。その意味では、「意図的」に、for文を使わずにeach文や、その他のループ文を使うという手もあります。

while

        • while(条件)do

処理

end

times

        • n.times do

処理

end

*1 10.times(10回)など、規定回数ループするときに使います

--- Python

条件判断

var ==1 (数値)

使える演算子:==, >, >=, <, <=, != など

var == "test" (文字列)

使える演算子:==, >, >=, <, <=, != など

変数内の文字列が、特定の文字列を含んでいるかどうか、というときは

'keyword' in var

と書きます。正規表現でマッチングするときは、import re を書いておいた上で

re.search('pattern', var)

と書きますが、PerlやRubyと異なり、結果がTrue/Falseではなく、マッチした結果か、Noneが返ってきます。ちょっと癖のある仕様だなと思います。(条件文が書きづらい)

*1 文字列の正規表現マッチングは、変数varが「数値」だとErrorになります。

*2 「含まれる」という意味合いでは、re.search(...)を使います。

*3 「合致する」という意味合いでは、re.match(...)を使います。

未定義変数かどうかは

'var' in locals()

を使います。shellの環境変数を拾うには、import os を書いておいて、

os.environ.get('ENV',"hoge")

と書きます。"ENV"は環境変数名を指定します。hogeは、指定した環境変数が存在しない時に返す値です。

条件分岐

if

        • if 条件: 処理(1行処理)
        • if 条件:

処理

elif 条件:

処理

else:

処理

*1 else if 文はelif(elsifではない)のでお間違えないようにしてください。

*2 Pythonに標準的なswitch文はありません

ループ

for

        • for var in リスト :

処理

*1 リスト は、配列であったり、range(1,10)などで表記します。

*2 var は、ローカル変数ではないので、外に同じ名前の変数があると、破壊してしまいます。

*3 range(1,10)と書いた場合、展開されるのは1~9までなので、注意してください

while

        • while 条件 :

処理