Day 4
.Conditional statement -條件陳述
.Iterative (Looping) Constructs - 迴圈
.File I/0 - 檔案的輸入與輸出
.Subroutine constructs - 如何寫副程式
4條件陳述、迴圈要檔案輸出/輸入與副程式撰寫
P64
什麼是真的(Truth)
.在Perl裡,truth一定以scalar的方式呈現
.除了" “ 及” 0"以外的字串都是True
.除了0以外的數字都是true
.任何參照(reference)都是true
.任何 undef()的值都是false
4-1什麼是true 以及false?
範例:
0 #會是一個字串,所以是false
1 #會是一個字串,所以是true
10-10 #10-10 = 0,然後再被轉換成字串"0",所以是false
0.00 #結果是0,然後再被轉換成字串"0",所以是false
“0” #會是一個字串,所以是false
“” #空的字串,所以是false
“0.00” #該字串並不是空的,也不完全是"0",因此是true
“0.00”+0 #計算結果後為0,所以是false
\$a #參照,所以是true
undef() #不被定義,所以是false
P68
.C style 的for迴圈
.接受三個expression
1、第一個:設字迴圈中使用變數的初始值
2、第二個:檢查迴圈變數值
3、第三個:改變迴圈變數值
for ( $sold = 0 ; $sold < 10000; $sold += $purchase )
{
$available = 10000 - $sold;
print “$available tickets are available. How many would you like: ”;
$purchase = ;
chomp($purchase);
}
4-2-2迴圈 for ()
執行迴圈的順序:
1、第一次迴圈先讀取迴圈變數初始值(第一個expression),並檢查第二個expression是否為真,如是,則執行大括號內的敘述。
2、第一次迴圈結束以前(敘述執行完),執行第三的expression。
3、先檢查第二個expression是否為真,如是,則進行第二次迴圈;如不是則停止迴圈。
4、第二次迴圈結束前執行第三個expression。
for ( $sold = 0 ; $sold < 10000; $sold += $purchase )
{
$available = 10000 - $sold;
print “$available tickets are available. How many would you like: ”;
$purchase = ;
chomp($purchase);
}
P69
迴卷 -for (2)
.簡單的遞增方式
for ( 1 .. 10000 )
{
print $_, “\n” ;
}
P70
迴圈 - foreach
.使用機率比for 迴圈大的多
.用來處理一連串的scalar
foreach $user ( @users )
{
if ( -f “/home/$user/.nexrc” -
{
print “$user is cool… they use a perl-aware vi!\n”;
}
}
p71
迴圈 - breaking out
.跳出迴圈的方式:next, last
.用以改變迴卷執行敘述的流程
.next: 跳離以下敘述,直接執行另一個迴圈
.last:跳離整個敘述區塊
foreach $user ( @users )
{
if ($user eq “root” or $user eq “lp” )
{
next;
}
if ($user eq “special”)
{
print “found the special account.”,\“;
last;
}
}
4-2-4跳出迴圈 - breaking out
foreach $user ( @users )
{
if ($user eq "root” or $user eq “lp” )
{
next;
}
if ($user eq “special”)
{
print “found the special account.”,\“;
last;
}
}
print "Enter string: ”;
While (($line = ) =~ /\d/) # 一般來講,代表鍵盤的輸入
{
print “$line\n”;
print “Enter string: ”;
}
print “Enter string: ”;
while (($line = ) ! ~ /\d/) # 只要$line沒有數字的話,程式繼續跑
{
print “$line\n”;
print “Enter string: ”;
}
print “Enter string: ”;
while (($line = ) !~ /\squit\s$/i)
{
print “$line\n”;
print “Enter string: ”;
}
P73
Perl 內建何留陣列變數 - @ARGV
.指令行各部份的名稱:
#exmaple.pl -d foo bar
#example.pl 程式或指令名稱,可以用保留變數$0代表
-d:參數
foo bar: 引數(argument)
.每個引數會成為@ARGV中的元件
.依照順序收入@ARGV中
.以上面例子而言:$ARGV [ 0 ] 是foo
4-2-5 Perl 內建的保留陳列變數- @ARGV
P74
檔案存取 - File Access
.File Handle - 可給任何名稱,通常給大寫
.開啟檔案 -
open (File Handle, 檔案所在位置)
.讀取檔案File Handle的內容 -
.把資料寫入新檔案的方式 - print FileHandle變數
.close (File Handle) - 關閉檔案
4-3 檔案存取File Access
p75
自訂副程式 - subroutine
.宣告副程式:
sub 函式名稱
{
…
}
.副程式內,接收輸入參數的預設陣列變數: @_
.區域(local)變數宣告:my
.函式回傳值的方式:return <值>
4-4自訂副程式
################檔案存取###########
die “Usage: $0 in file outfile\n” if @ARGV ! = 2;
open( INFILE, “$ARGV[0]”) || die “ Cannot open $ARGV [0] for reading. \n”;
open( OUTFILE, “$ARGV[1]”) || die “ Cannot open $ARGV [1] for writing. \n”;
@lines = ; #### 一次讀完整個檔案;每一行就是陳列的一個元件
上面的方式也可以寫成
push ( @line,$_) while ;
foreach $line ( @lines)
{
print OUTFILE $ line if $ line =~m/#/;
}
close ( INFILE );
######## 在開啟一次檔案前,無須關閉檔案
open ( OUTFILE, “$ARGV [1]” ) || die “Cannot open $ARGV [1] for reading. \n”;
print while (); #### 預設使用$_變數!
close ( OUTFILE );
################純量及陳列的函式參數################
@list = ( “foo”,“bar”,“snafu”,“ouch”,“opps”);
$oneline = run_together(@list);
print “\n$oneline\n”;
@address_parts = (“John Doe”, 123 Main Street", Nowhere, CA 90000");
print_envelope( @address_parts );
sub runtogether
{
my ( @list ) = <a href=“twitter:@”>@_;
my ( $str, $sting );
$string = “”;
foreach $str ( @list )
{
$string .= $str;
}
return $string;
}
sub printenvelope
{
my ($name, $street, $city_state_zip ) = <a href=“twitter:@”>@_;
print “$name\n”;
print “$street\n”;
print “$city_state_zip\n\n”;
}
sub hadprint
{
my ( @list1, @list2) = <a href=“twitter:@”>@_;
my $element;
foreach $element ( @list1 )
{
print $ element, “\n”; #### 看看輸出代表什麼意義
}
}
課堂實作:請分析access_log.16的內容,分別找出IP,時間及URL的統計,並寫出一個副程式把結果仙到標準輸出
#!/usr/bin/perl
$total _hit = 0;
$dir = “/tmp/logs”;
$filename = “access_log.16”;
open( FILE, “$dir/filename”) or die “Can't open file!\n”;
while ()
{
chomp;
$_ =~ /.*?\s.?[.?:(\d{2}).?“(.?)/;
$ip { $1 }++;
$hour_hits{ $2 }++;
$url{ $3 }++;
}
close ( FILE );
print_hash ( %ip );
sub printhash
{
my ( %hash ) = <a href="twitter:@”>@;
foreach ( sort { &hash { $a } $hash { $b }} keys %hash)
{
print “$ => $hash { $_ }\n”;
$total hits += $ hash { $ };
}
}
沒有留言:
張貼留言