以前看《perl24》书做的部分笔记
第一部分 perl基础
一、 Perl入门
perl –v
#!/usr/bin/perl –w
#!/usr/bin/env perl
perldoc perl
perldoc tf print
perldoc –q support
二、 perl 的基本构件:数字和字符串
qq和q运算符可以使用任何非字母、非数字字符来标记字符串的开始和结束。这些标记成为界限符。
特殊变量$_
收集了一下perl的一些特殊变量
$- 当前页可打印的行数,属于Perl格式系统的一部分
$! 根据上下文内容返回错误号或者错误串
$” 列表分隔符
$# 打印数字时默认的数字输出格式
$$ Perl解释器的进程ID
$% 当前输出通道的当前页号
$& 与上个格式匹配的字 符串
$( 当前进程的组ID
$) 当前进程的有效组ID
$* 设置1表示处理多行格式.现在多以/s和/m修饰符取代之.
$, 当前输出字段分隔符
$. 上次阅读的文件的当前输入行号
$/ 当前输入记录分隔符,默认情况是新行
$: 字符设置,此后的字符串将被分开,以填充连续的字段.
$; 在仿真多维数组时使用的分隔符.
$? 返回上一个外部命令 的状态
$@ Perl解释器从eval语句返回的错误消息
$[ 数组中第一个元素的索引 号
$\ 当前输出记录的分隔符
$] Perl解释器的子版本号
$^ 当前通道最上面的页面输出格式名字
$^A 打印前用于保存格式 化数据的变量
$^D 调试标志的值
$^E 在非UNIX环境中的操作系统扩展错误信息
$^F 最大的文件捆述符数值
$^H 由编译器激活的语法检查状态
$^I 内置控制编辑器的值
$^L 发送到输出通道的走纸换页符
$^M 备用内存池的大小
$^O 操作系统名
$^P 指定当前调试值的内部变量
$^R 正则表达式块的上次求值结果
$^S 当前解释器状态
$^T 从新世纪开始算起,脚步本以秒计算的开始运行的时间
$^W 警告开关的当前值
$^X Perl二进制可执行代码的名字
$_ 默认的输入/输出和格式匹配空间
$| 控制对当前选择的输出文件句柄的缓冲
$~ 当前报告格式的名字
$` 在上个格式匹配信息 前的字符串
$’ 在上个格式匹配信息 后的字符串
$+ 与上个正则表达式搜索格式匹配 的最后一个括号
$< 当前执行解释器的用户的真实ID
$ 含有与上个匹配正则表达式对应括号结果
$= 当前页面可打印行的数目
$> 当前进程的有效用户ID
包含正在执行的脚本的文件名
$ARGV 从默认的文件句柄中读取时的当前文件名
%ENV 环境变量列表
%INC 通过do或require包含的文件列表
%SIG 信号列表及其处理方式
@_ 传给子程序的参数列表
@ARGV 传给脚本的命令行参数列表
@INC 在导入模块时需要搜索的目录列表
$-[0]和$+[0] 代表当前匹配的正则表达式在被匹配的字符串中的起始和终止的位置 。
三、 控制程序流
四、 基本构件的堆栈:列表与数组
在 perl 中,数组变量用一个符号(@)后随一个有效的变量名。
如果赋值数组左边的列表只包含变量名,那么该列表可以用来对其元素进行初始化。请
看下面这个例子:
($a, $b, $c)=qw (apples oranges bananas);
Split函数与join函数
例子:
suse10:/home/perl # cat hangman04.pl
#!/usr/bin/perl -w
@words = qw ( internet answers printer program );
print @words;
@guesses = ();
$wrong=0;
$choice = $words[rand @words];
$hangman = "0-|--<";
@letters=split(//, $choice);
@hangman=split(//, $hangman);
@blankword=(0) x scalar(@hangman);
OUTER:
while ($wrong<@hangman){
foreach $i (0..$#letters) {
if ($blankword[$i]) {
print $blankword[$i];
} else {
print "-";
}
}
print "\n";
if ($wrong) {
print @hangman[0..$wrong-1]
}
print "\n your guess: ";
chomp($guess=<STDIN>);
foreach(@guesses) {
next OUTER if ($_ eq $guess);
}
$right=0;
for ($i=0; $i<@letters; $i++) {
if ($letters[$i] eq $guess) {
$blankword[$i]=$guess;
$right=1;
}
}
$wrong++ unless(not $right);
if (join('', @blankword) eq $choice) {
print "you got it right! \n";
exit;
}
print "wrong:".$wrong."\n";
print "right:".$right."\n";
print "guesses:".@guesses."\n";
}
print "$hangman \n sorry, the word was $choice.\n";
五、 进行文件操作
每当需要访问磁盘上的文件时,必须创建一个新的文件句柄,并且打开该文件句柄,进
行相应的准备。当然必须使用o p e n函数来打开文件句柄。O p e n的句法如下:
open (filehandle, pathname)
o p e n函数将文件句柄作为它的第一个参数,将路径名作为第二个参数。路径名用于指明
要打开哪个文件,因此,如果没有设定完整的路径名,比如c : / w i n d o w s / s y s t e m /,那么o p e n函数将设法打开当前目录中的文件。如果o p e n函数运行成功,它将返回一个非0值。如果o p e n函数运行失败,它返回u n d e f(假):
open (WJLCN, "/home/perl/test")||die;
#$line=<WJLCN>;
#print $line;
#while(defined($a=<WJLCN>)){
#print $a;
#}
while(<WJLCN>){print $_;}
close(WJLCN);
if (open (T1, "/home/perl/test")) {
print 'running!'."\n";
} else {
print "connot open T1\n";
exit 1;
}
六、 模式匹配
Grep函数的使用
Grep不一定必须与模式匹配或替
换运算符一道使用,它可以与任何运算符一道使用。
例如:
@dogs=qw ,geryhound cloud bloodhound china chinc,;
#@hounds=grep /hound/, @dogs;
@hounds=grep s/hound/hounds/, @dogs;
@longdogs=grep length($_)>9, @dogs;
Map函数使用
一个相关函数m a p的句法与g r e p基本相同,不过它的表达式(或语句块)返回的值是从m a p返回的,而不是$ 的值。可以使用m a p函数,根据第一个数组来产生第二个数组。下面是该函数的一个例子:
@ words= map {split ' ',$_} @ input;
在这个例子中,数组@ i n p u t的每个元素(作为$ 传递给语句块)均用空格隔开。这意味着@ i n p u t的每个元素均产生一个单词列表。该列表存放在@ w o r d s中。@ i n p u t的每个相邻行均被分隔开来,并在@ w o r d s中进行累加。
七、哈希结构
Keys函数
Values函数
suse10:/home/perl # cat customer.pl
#!/usr/bin/perl -w
open(PH, "customers.tet") or die "connot open customers.tet: $!\n";
while(<PH>){
chomp;
($number, $email)=(split(/\s+/, $_))[1,2];
$Phone{$number}=$_;
$Email{$email}=$_;
}
close(PH);
print "type 'q' to exit\n";
while(1){
print "\n number? ";
$number=<STDIN>; chomp($number);
$address="";
if(! $number){
print "e-mail?";
chomp($address=<STDIN>);
}
next if(! $number and ! $address);
last if($number eq 'q' or $address eq 'q');
if($number and exists $Phone{$number}){
print "customer: $Phone{$number}\n";
next;
}
if($address and exists $Email{$address}){
print "customer: $Email{$address}\n";
next;
}
print "customer record not found.\n";
next;
}
print "\nall done.\n";
第6行:$ 中的这一行在白空间处( \ s +)被分割。s p i l t语句的前后加上一组括号,后面是
方括号。由于你只对每一行上的电话号码和电子邮件地址感兴趣,所以从分割的语句中取出
一部分返回值。这两个值被赋予$ n u m b e r和$ e m a i l。
Foreach(sort keys %words){print “$_ $words{$_}\n”}
八、函数
实例:
查看帮助文档:perldoc –f sort
suse10:/home/perl # cat -n stats_sub.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4 sub mean {
5 my(@data)=@_;
6 my $sum;
7 foreach(@data) {
8 $sum+=$_;
9 }
10 return($sum/@data);
11 }
12 sub median {
13 my(@data)=sort { $a <=> $b } @_;
14 if (scalar(@data)%2){
15 return($data[@data/2]);
16 } else {
17 my ($upper, $lower);
18 $lower=$data[@data/2];
19 $upper=$data[@data/2-1];
20 return(mean($lower, $upper));
21 }
22 }
23 sub std_dev{
24 my (@data)=@_;
25 my ($sq_dev_sum, $avg)=(0,0);
26
27 $avg=mean(@data);
28 foreach my $elem(@data){
29 $sq_dev_sum+=($avg-$elem)**2;
30 }
31 return(sqrt($sq_dev_sum/@data-1));
32 }
33 my($data, @dataset);
34 print "please enter data, separated by commas: ";
35 chomp($data = <STDIN>);
36 @dataset=split(/[\s,]+/, $data);
37
38 print "median: ", median(@dataset), "\n";
39 print "mean: ", mean(@dataset), "\n";
40 print "standard dev: ", std_dev(@dataset), "\n";
第二部分 高级特性
九、其他函数和运算符
Index 和 rindex 函数进行标量搜索
用substr分割标量
chop()函数,只是去除最后一个字符。
chomp()函数,就要首先判断最后一个字符是不是为"\n",他才去除。
suse10:/home/perl # cat -n employee.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4
5 my @employees=(
6 'wjl,jl,34521,9.33,38',
7 'wsf,sf,12332,10.22,39',
8 'wkk,kk,32123,10.11,40',
9 'ill,ll,34123,8.44,41',
10 'nio,io,23412,8.34,37',
11 );
12
13 sub print_emp {
14 my($last,$first,$emp,$hourly,$time)=
15 split(',', $_[0]);
16 my $fullname;
17 $fullname=sprintf("%s %s", $first, $last);
18 printf("%6d %-20s %6.2f %d %7.2f\n",
19 $emp, $fullname, $hourly, $time,
20 ($hourly * $time)+.005 );
21 }
22
23 @employees=sort {
24 my ($L1, $F1)=split(',', $a);
25 my ($L2, $F2)=split(',', $b);
26 print "l1:$L1 f1:$F1 l2:$L2 f2:$F2\n";
27 return( $L1 cmp $L2 #compare last name
28 || # if they're the same
29 $F1 cmp $F2 # compare first name
30 );
31 } @employees;
32
33 foreach(@employees){
34 print_emp($_);
35 }
suse10:/home/perl # perl employee.pl
l1:wjl f1:jl l2:wsf f2:sf
l1:wkk f1:kk l2:ill f2:ll
l1:wjl f1:jl l2:ill f2:ll
l1:wjl f1:jl l2:wkk f2:kk
l1:wsf f1:sf l2:wkk f2:kk
l1:ill f1:ll l2:nio f2:io
l1:nio f1:io l2:wjl f2:jl
34123 ll ill 8.44 41 346.04
23412 io nio 8.34 37 308.58
34521 jl wjl 9.33 38 354.55
32123 kk wkk 10.11 40 404.40
12332 sf wsf 10.22 39 398.59
suse10:/home/perl #
十、文件与目录
Unlink、mkdir、rmdir、rename
suse10:/home/perl # cat -n perl2410.pl
1 #!/usr/bin/perl -w
2
3 opendir(PERLDIR, '/home/perl')||die "cannot open /home/perl: $!";
4 #@files=readdir PERLDIR;
5 #@files=grep(!/^\.\.?$/, readdir PERLDIR);
6 @files=grep(/\.pl$/i, readdir PERLDIR);
7
8 closedir(PERLDIR);
9 #print @files;
10 foreach(@files){print "$_ ";}
11 print "\n";
12 #while(@files){print $_;}
13
14
15 print "directory to create ?\n";
16 chomp(my $newdir=<STDIN>);
17 mkdir($newdir, 0755)||die "failed to create $newdir:$!";
18
19 print "directory to be removed ?\n";
20 chomp(my $baddir=<STDIN>);
21 rmdir($baddir)||die "failed to removed $baddir:$!";
22
23 $kkk=unlink </home/perl/test123/*.txt>;
24 print $kkk;
suse10:/home/perl #
十一、系统之间的互操作性
System()函数、反引号、qx{}
捕获输出、管道
Print $^O;
ls -l |sort |perl perl2411.pl |more
suse10:/home/perl # cat -n perl2411.pl
1 #!/usr/bin/perl -w
2 #$ls=`ls -lt /`;
3 #print $ls;
4
5 #$hostname=`hostname`;
6 #print $hostname;
7
8 #system("vi kkkk");
9
10 use strict;
11 my($dirs, $sizes, $total);
12
13 while(<STDIN>){
14 chomp;
15 $total++;
16 if(-d $_){
17 $dirs++;
18 print "$_\n";
19 next;
20 }
21 $sizes += (stat($_))[7];
22 print $sizes;
23 print "$_\n";
24 }
25 print "$total files, $dirs directories\n";
26 print "average file size: ", $sizes/($total-$dirs), " \n";
27
28 print $^O;
suse10:/home/perl #
十二、使用perl的命令行工具
如何使用perl的调试程序。
如何使用命令行开关来编写perl程序。
suse10:/home/perl # perl -d employee.pl
Loading DB routines from perl5db.pl version 1.28
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(employee.pl:5): my @employees=(
main::(employee.pl:6): 'wjl,jl,34521,9.33,38',
main::(employee.pl:7): 'wsf,sf,12332,10.22,39',
main::(employee.pl:8): 'wkk,kk,32123,10.11,40',
main::(employee.pl:9): 'ill,ll,34123,8.44,41',
main::(employee.pl:10): 'nio,io,23412,8.34,37',
main::(employee.pl:11): );
DB<1> h
List/search source lines: Control script execution:
l [ln|sub] List source code T Stack trace
- or . List previous/current line s [expr] Single step [in expr]
v [line] View around line n [expr] Next, steps over subs
f filename View source in file <CR/Enter> Repeat last n or s
/pattern/ ?patt? Search forw/backw r Return from subroutine
M Show module versions c [ln|sub] Continue until position
Debugger controls: L List break/watch/actions
o [...] Set debugger options t [expr] Toggle trace [trace expr]
<[<]|{[{]|>[>] [cmd] Do pre/post-prompt b [ln|event|sub] [cnd] Set breakpoint
! [N|pat] Redo a previous command B ln|* Delete a/all breakpoints
H [-num] Display last num commands a [ln] cmd Do cmd before line
= [a val] Define/list an alias A ln|* Delete a/all actions
h [db_cmd] Get help on command w expr Add a watch expression
h h Complete help page W expr|* Delete a/all watch exprs
|[|]db_cmd Send output to pager ![!] syscmd Run cmd in a subprocess
q or ^D Quit R Attempt a restart
Data Examination: expr Execute perl code, also see: s,n,t expr
x|m expr Evals expr in list context, dumps the result or lists methods.
p expr Print expression (uses script's current package).
S [[!]pat] List subroutine names [not] matching pattern
V [Pk [Vars]] List Variables in Package. Vars can be ~pattern or !pattern.
X [Vars] Same as "V current_package [Vars]". i class inheritance tree.
y [n [Vars]] List lexicals in higher scope <n>. Vars same as V.
e Display thread id E Display all thread ids.
For more help, type h cmd_letter, or run man perldebug for all docs.
DB<1>
十三、引用与结构
suse10:/home/perl # cat -n perl2413_maze.pl
1 #!/usr/bin/perl -w
2 use strict;
3
4 my @maze=(
5 [ qw( e swe we ws ) ],
6 [ qw( ne new sw ns )],
7 [ qw( ns - ns wn ) ],
8 [ qw( ne w ne w )],
9 );
10 my %direction=(n=> [ -1,0], s=> [1,0],
11 e=>[ 0,1], w=>[0, -1]);
12
13 my %full=( e=> 'East', n=>'North', w=>'West', s=>'South');
14 my($curr_x, $curr_y, $x, $y)=(0,0,3,3);
15 my $move;
16
17 sub disp_location {
18 my($cx, $cy)=@_;
19 print "you may move ";
20 while ($maze[$cx][$cy]=~/([nsew])/g){
21 print "$full{$1}";
22 }
23 print "($maze[$cx][$cy])\n";
24 }
25 sub move_to{
26 my($new, $xref, $yref)=@_;
27
28 $new=substr(lc($new),0,1);
29 if($maze[$$xref][$$yref]!~/$new/){
30 print "invalid direction, $new.\n";
31 return;
32 }
33 $$xref += $direction{$new}[0];
34 $$yref += $direction{$new}[1];
35 }
36
37 until ( $curr_x == $x and $curr_y == $y){
38 disp_location($curr_x, $curr_y);
39 print "which way? ";
40 $move=<STDIN>; chomp $move;
41 exit if ($move=~/^q/);
42 move_to($move, \$curr_x, \$curr_y);
43 }
44
45 print "you made it through the maze! \n";
suse10:/home/perl #
十四、使用模块
使用English模块
Use English;
While(<>){
Print $ARG;
}
特殊变量 :英文名
$_ $ARG
@_ @ARG
$! $OS_ERROR
$^O $OSNAME
$0 $PROGRAM_NAME
Use diagnostics
使用模块的例子:
suse10:/home/perl # cat -n perl2414.pl
1 #!/usr/bin/perl -w
2 use strict;
3 use File::Find;
4
5 sub wanted {
6 if($_ eq "test"){
7 print $File::Find::name,"\n";
8 }
9 }
10 find \&wanted, '/home/perl';
11
12 use File::Copy;
13 copy("/home/perl/guess.pl", "/home/perl/kkki/")||warn "could not copy files:$!";
14 if(not move("/home/perl/kkki/guess.pl", "/home/perl/kkki/test.pl")){
15 warn "guess.pl could not be move: $!";
16 unlink "/home/perl/kkki/test.pl";
17 }
18
19
20 use Net::Ping;
21 if ( pingecho("www.baidu.com", 5) ){
22 print "google is on the network.";
23 } else {print "google is unreachable.";}
suse10:/home/perl #
十五、了解程序的运行性能
DBM文件
一种自由格式备忘记事板
suse10:/home/perl # cat -n perl2415.pl
1 #!/usr/bin/perl -w
2 use strict;
3
4 my (%answers, $subject, $info, $pattern);
5
6 dbmopen(%answers, "answers", 0666)||die "cannot open answer DBM: $!";
7 while(1){
8 print "your question ('quit' to quit): ";
9 chomp($_=lc(<STDIN>));
10 last if(/^quit$/);
11 if(/like\s+(.*)\?/){
12 $pattern=$1;
13 while( ($subject, $info)=each(%answers) ){
14 if ($subject=~/$pattern/){
15 print "$subject is like $pattern\n";
16 }
17 }
18 } elsif (/(.*)\?/){
19 $subject=$1;
20 if($answers{$subject}){
21 print "$subject is $answers{$subject}\n";
22 } else {
23 print qq{i don't know about "$subject"\n};
24 }
25 } elsif (/(.*)\sis\s(.*)/) {
26 $subject=$1;
27 $info=$2;
28 $answers{$subject}=$info;
29 print qq{ok, i'll remember "$subject" as "$info"\n};
30 } else {
31 print "i'm sorry, i don't understand.\n";
32 }
33 }
34 dbmclose(%answers);
suse10:/home/perl #
get_lock()、release_lock()、readdata()、writedata()函数的使用
十六、perl 语言开发界
CPAN
第三部分 perl用于CGI
十七、CGI概述
suse10:/usr/local/apache2/cgi-bin # cat perl2417.pl
#!/usr/bin/perl -w
use CGI qw(:standard);
use strict;
print header;
print "<B>hello, world!";
print "<br />";
$a=`date`;
print "<I>$a</I>";
suse10:/usr/local/apache2/cgi-bin #