發新話題

網路管理語言 Perl 入門與實作

5. 流程控制
我們經常會視某一情況的不同而有不同的處理動作,稱之為流程控制。

5.1 if 控制結構
if 有四種形式:
引用:
第 1 種:

if (條件判斷為真) {
        做某些事情 ....
}


第 2 種:

if (條件判斷為真) {
        做某些事情 ....
} else {
        做另一些事情 ....
}


第 3 種:

if (條件判斷 1 為真){
        做某些事情 ....
} elsif (條件判斷 2 為真)
        做另一些事情 ....
} else {
        不然做這些事情 ....
}


第 4 種:(後置式)

做某事 if (條件判斷為真);

例:

print "I dont't like it !\n" if ($yourANS eq '我不喜歡輸的感覺');
當然,elsif 可以不限次數 ....

注意 1:{ } 不可以省略

注意 2:是 elsif, 不是 elseif,中間沒有 e 喔!

用例
數學三一律
引用:
if ($a > $b) {
   print '$a 大於 $b';
} elsif ($a == $b) {
   print  '$a 等於 $b';
} else {
   print  '$a 小於 $b';
}
注意:判斷有沒有相等是用 == 而不是 =

[ 本帖最後由 蔡逸竹 於 2006-10-26 22:03 編輯 ]

TOP

5.2 unless 控制結構
if 是判斷條件為真時做某事,unless 剛好相反:unless 是判斷條件為假時做某事。

unless 有三種形式:
引用:
第 1 種:

unless (條件判斷為假) {
        做某些事情 ....
}


第 2 種:

unless (條件判斷為假) {
        做某些事情 ....
} else {
        做另一些事情 ....
}

第 3 種:(後置式)

做某事 unless (條件判斷為假);

例:

print "I do like it !\n" unless ($yourANS eq '我不喜歡輸的感覺');
用例
引用:
# 除非 192.168.1.2 的主機名稱存在,否則:

unless (exists $HOSTNAME{'192.168.1.2'}) {
   print "主機名稱不存在!\n";
} else {
   print  "主機名稱為 $HOSTNAME{'192.168.1.2'}";
}

TOP

5.3 until 控制結構
until 是指直到某事為真之前(若它為假),都一直做某事。

until 有二種形式:
引用:
第 1 種:

until (條件判斷為假) {

        一直做某事;

}

例:

until ($sun eq 'is down') {

        print "現在是白天 ....\n";
}



第 2 種:(後置式)

一直做某事 until (條件判斷為假);


例:

$i++ until ($i > 1000);



第 3 種:

do {
        一直做某事

} until (條件判斷為假);

例:

#! /usr/bin/perl

do {

        print "$j\n";
        $j++;

} until ($j>=10);

# 輸出結果:
1
2
3
4
5
6
7
8
9

TOP

5.4 for 控制結構
for 是迴圈的一種,經常被使用在固定迴圈次數時(但不一定,也可能產生無窮迴圈)。
引用:
#! /usr/bin/perl

for ($i=1; $i<=100; $i++) {
        $sum += $i;
}

print "總和:$sum\n";
特別注意!!!! foreach 和 for 是可以互用的,也就是說以下例子,結果同上。
引用:
#! /usr/bin/perl

# 使用 foreach
foreach ($i=1; $i<=100; $i++) {
        $sum += $i;
}

print "總和:$sum\n";

TOP

5.5 while 控制結構
while 是迴圈的一種,經常被使用在某些資料存在時:
引用:
第 1 種:

while ( ($k, $v) = each %HASH ) {
        print "$k ===> $v\n";
}


第 2 種:
do {

        $i++;

        print $i, "\n";

} while ( $i < 100 );



第 3 種:使用 continue block

$i=1;
while ($i < 10) {

        print $i, "\n";

} continue {

        $i++;
}

TOP

5.6 foreach 控制結構
引用:
#! /usr/bin/perl

@ALL=(1, 3, 5, 7, 9);
foreach $num (@ALL) {
        print "$num\n";
}

# foreach 會將 @ALL 陣列中的元素,逐一代入 $num 中,然後在迴圈中顯示 $num,一直到 @ALL 所有元素都輪完為止。


#! /usr/bin/perl

foreach $p ('John', 'Marry', 'Kenny', 'Dice') {
        print "Hi! $p\n";
}
特別注意!!!! foreach 和 for 是可以互用的,也就是說以下例子,結果同上。
引用:
#! /usr/bin/perl

@ALL=(1, 3, 5, 7, 9);

# 寫 for 相當於 foreach
for $num (@ALL) {
        print "$num\n";
}
用例
以下這支程式是一支 CGI 程式,請放入 cgi-bin 目錄中,然後 chmod +x env.cgi,即可在瀏覽器中觀看。它會顯示目前的所有的環境變數。

檔名:env.cgi
引用:
#!/usr/bin/perl

print "Content-type: text/html\n\n";

print "\n";

foreach (keys %ENV) {
   print $_." ===> ".$ENV{$_}."<br>\n";
}

print "\n";
註:這片光碟中,apache 的設定檔在 /etc/apache/httpd.conf,cgi-bin 的實際路徑我已把它改到 /var/tmp,這是 ramdisk 的一部份,如此,我們才能把 cgi 程式寫入。(KNOPPIX CD 是燒死的,原 cgi-bin 目錄區無法寫入)

TOP

5.7 迴圈控制
Perl 常見的迴圈有 while、for、foreach、until,在每一種迴圈中,可以視情況,使用以下三種算符,來控制迴圈。
引用:
last 一次只能跳出一層迴圈

語法:last

用例:

$i=0;
while ($i<=100) {

        $i++;
        last if ($i==10); # 當 $i 等於 10 時,跳出 while 結束迴圈。
        print "$i\n";
}



若要一次跳出多層迴圈,必須採用標記:

語法:last 標記

用例:

#! /usr/bin/perl

$i=0;
$j=0;

OUT: while ($j<=100) {

        $j++;

        while ($i<=100) {

                $i++;
                last OUT if ($i==10); # 當 $i 等於 10 時,跳至最外圈。
                print "$i\n";
        }

        print "我是 j : $j\n";
}




next

next 標記

用例:

$i=0;
while ($i<=100) {
        $i++;
        next if ($i==10); # 當 $i 等於 10 時,跳過去,不執行 print 的動作
        print "Now is $i\n";
}



redo 表示剛剛執行的那一次不算,index 值不增加,重做一次!

redo

redo 標記

用例:

for ($i=1; $i<=100; $i++) {
        print "請輸入數字 $i:";
        chomp($keyin=<STDIN>);
        if ($keyin != $i) { # 若打錯了,再要求重打一次
                print "抱歉! 您打錯了! 是 $i 才對! 請重打一次!\n";
                redo;
        } else {
                print "很好! 我喜歡!\n";
        }
}

# 測試結果:

請輸入數字 1:1
請輸入數字 2:2
請輸入數字 3:3
請輸入數字 4:5
抱歉! 您打錯了! 是 4 才對! 請重打一次!
請輸入數字 4:6
抱歉! 您打錯了! 是 4 才對! 請重打一次!
請輸入數字 4:9
抱歉! 您打錯了! 是 4 才對! 請重打一次!
請輸入數字 4:10
抱歉! 您打錯了! 是 4 才對! 請重打一次!
請輸入數字 4:4
請輸入數字 5:5
請輸入數字 6:6
請輸入數字 7:7
請輸入數字 8:8
請輸入數字 9:9

TOP

5.8 三元運算子
三元運算子是程式老手最愛用的一種流程控制寫法。
引用:
#! /usr/bin/perl

chomp($i=<STDIN>);

$rt = ($i == 10) ? 'yes' : 'no'; # 若 $i 等於 10,則 $rt 為 yes,否則 $rt 為 no

print "$rt\n";
上式其實可以用 if 來改寫:
引用:
#! /usr/bin/perl

chomp($i=<STDIN>);

if ($i == 10) {
        print "yes\n";
} else {
        print "no\n";
}

TOP

6. 檔案處理
本章介紹 Perl 檔案處理的方法。

6.1 檔案代碼
想要學會檔案處理,必須先瞭解 File Handle(檔案代碼) 的觀念:當你開啟一個檔案時,系統會傳回一個代碼,用來代表已開啟的檔案,透過它,便可以對這個檔案進行存取的動作。

TOP

6.2 開檔關檔
Perl 處理檔案開啟的方式有以下幾種:(FHD 為檔案代碼)
引用:
* 唯讀 (以下二種方式作用相同)

      open(FHD, "檔名") || die "$!\n";
      open(FHD, "< 檔名") || die "$!\n";
       
* 開啟新檔,以供寫入

      open(FHD, "> 檔名") || die "$!\n";
       
* 開啟檔案,以增添附加的方式寫入

      open(FHD, ">> 檔名") || die "$!\n";
       
* 開啟舊檔,以供讀寫

      open(FHD, "+< 檔名") || die "$!\n";
       
* 開啟新檔,以供讀寫

      open(FHD, "+> 檔名") || die "$!\n";
       
* 開啟檔案,以供讀寫或增添附加

      open(FHD, "+>> 檔名") || die "$!\n";
       
* 開啟一道管線(pipe),以輸出至某一程式或命令

      open(FHD, " | 命令") || die "$!\n";
       
* 開啟一道管線(pipe), 以讀取某一程式或命令的結果

      open(FHD, "命令 |") || die "$!\n";
       
檔案處理完之後,應該養成良好習慣,將檔案關閉,方法如下:
引用:
    * close(FHD);
用例:
引用:
#!/usr/bin/perl

# 指定檔案名稱
$file_name="test.txt";

#-----------------------------------------------------------------
# 例一: 讀檔
#-----------------------------------------------------------------
# 唯讀模式開檔
open(FHD, "$file_name") || die "$!\n";

@all=<FHD>; # 讀出所有的檔案內容

# 或

while (my $line=<FHD>) {

        chomp $line;
    進一步處理 ....

}

# 關檔
close(FHD);

#-----------------------------------------------------------------
# 例二: 開新檔案以供寫入
#-----------------------------------------------------------------
# 開檔
open(FHD, "> $file_name") || die "$!\n";

#寫入
print FHD "Hello, world !\n";

# 關檔
close(FHD);

#-----------------------------------------------------------------
# 例三: 開啟檔案、增添資料
#-----------------------------------------------------------------
# 開檔
open(FHD, ">> $file_name") || die "$!\n";

# 增添
print FHD "Hey! What a lie!\n";

# 關檔
close(FHD);
用例一:
引用:
#! /usr/bin/perl

# 檔案路徑請自行修改:
$file="/home/ols3/tmp/index.html";

# 開檔
open(FHD, "$file") || die "$!\n";

# 讀出整份檔案內容
@all=<FHD>;

# 關檔
close(FHD);

$i=0;
foreach (@all) {
    $i++;
        # 印出每一列
    print;  # 作用對像為預設變數 $_
    # 只印計數前 10 列
    last if ($i > 10); # 若 $i > 10,last 會跳出迴圈
}
用例二:
引用:
#! /usr/bin/perl

# 執行法:
# chmod +x newcat.pl
# ./newcat.pl 路徑檔名
# 它會將該檔複製放入 newlog.txt 中

$file=$ARGV[0];

$log="newlog.txt";

open(FHD, "$file") || die "開啟 $file 失敗! 請檢查 $file !!!\n";

open(W, "> $log") || die "$!\n";

while (my $line=<FHD>) {

        print W $line;

}

close(W);
close(FHD);
用例三:
引用:
#! /usr/bin/perl

$csv="studdemo.csv";

open(FHD, "$csv") || die "無法讀取 $csv 檔! 請查明原因!\n";

while (my $line=<FHD>) {

        chomp $line;

        ($f1, $name, $f3, $f4, $f5, $f6, $f7, $pslno, $par, $f10)=split(/,/ , $line);

    print "學生 $name 的身份證字號是 $pslno,其父為 $par 先生\n";
}

close(FHD);

# studdemo.csv 的內容如下:

代號,姓名,性別,入學年,班級,座號,生日(西元),身份證字號,父親姓名,母親姓名,郵遞區號,電話,住址(不含縣市?鎮),緊急聯方式
086011,林開廉,1,86,2,1,1996/2/5,L23456700,林xx,廖xx,435,262343827,下寮裡中和街4號,0923-032870.26231296.
086012,柯政宇,1,86,2,2,1996/6/2,L14564300,柯xx,洪xx,435,67644381,文化裡7鄰東建路1號,(母)0923-032870.
086013,張勛和,1,86,2,3,1996/7/28,N15544000,張xx,陳xx,435,26341262,安仁裡5鄰梧棲路9號,0931-549242.
086014,林志成,1,86,2,4,1996/8/14,L18775000,林xx,童xx,435,265345337,中正裡7鄰中興路18巷2,0953-6916677
086015,蔡庚江,1,86,2,5,1996/2/25,L23343000,蔡xx,鄒xx,435,23453422,中正裡19鄰梧棲路11巷2號,26562451
086016,陳信宏,1,86,2,6,1996/6/5,L123253000,陳xx,鄭桂妙,435,4461943,中正裡中興路18巷1弄12號,0921-728850.
086017,林德晉,1,86,2,7,1996/7/8,L133435000,張xx,,2634521,435,中正裡3鄰仁美街3巷69號,26573434
086018,林承佑,1,86,2,8,1995/10/2,L779334000,林xx,林xx,2654348,434,南寮村8鄰中沙路2號,0912-667788.
086019,陳科全,1,86,2,9,1996/3/2,L1252343000,陳xx,黃xx,34534561,435,草湳裡建國北街24號2樓,0923-243445.
086020,陳柏仁,1,86,2,10,1995/11/6,L125231000,陳xx,黃xx,25454542,435,草湳裡1鄰梧南路2號之11,0923-300889.
用例四:將結果存在一個新檔 stu.log 中。
引用:
#! /usr/bin/perl

use strict;

my $file=$ARGV[0] || die "請至少要指定一個用逗點分開的 csv 資料檔名!!!\n";

my $log="stu.log";

open(FHD, "$file") || die "開啟 $file 失敗! 請檢查 $file !!!\n";

open(W, "> $log") || die "$!\n";

while (my $line=<FHD>) {

        chomp $line;

        my ($f1, $name, $f3, $f4, $f5, $f6, $birthday, $pslno, $papa, $nouse) = split(/,/  , $line);

        print W "學生:$name,生於:$birthday,其身份證字號為:$pslno,其父為:$papa\n";

}

close(W);
close(FHD);

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。