Perl学习笔记五

作者:Ajian 发布时间:August 17, 2009 分类:Perl

前言:《Perl语言入门(第四版)》这本书,最后三章看完了,可以说对perl有个基本的认识的,其实我觉得如果学过PHP的人来学这个,真是简单的不能再简单了,不过也可能会觉得他那“丑”了,但对于一个系统管理员来说Perl是一个很好的管理程序,何况像Perl这种语言基本都是系统自带的,就像Shell一样调用方便,这样才会让你可以自由的移动到不同的服务器上,直接进行操作等。之后的学习就是实践了,多看多回顾,最快的学习方法就是亲手写,解决了几个问题之后就会熟练了。

第十三章 字符串和排序
Perl 被设计成 90%擅长处理文本,10%处理其余的问题。

1、 使用索引寻找子串
index 函数
$where = index($big, $small);
index 函数总是报告子串出现的第一个位置。
某个子串最后出现的位置
my $last_slash = rindex("/etc/passwd","/"); #值为 4

2、 使用 substr 操作子串
substr 只处理部分的字符串
$part = substr($string, $initial_position, $length);
my $mineral = substr("Fred J. Flintstone", 8, 5);#得到“Flint”
它有三个参数:一个字符串,一个从 0 开始编号的初始位置(类似于 index 的返回值),以及子串的长度

index 和 substr 可以很好的一起工作。在本例中,我们提取出了字符串中字母 l 后的子串。
my$ $long = "some very very long string";
my $right = substr($long, index($long, "l" ));
如果想明确要求到达字符串的结尾处,无论其或长或短,可以像下例那样省略掉第三个参数.

3、 使用 sprintf 格式化数据
sprintf 函数的参数和 printf 的参数完全相同(除了可选的文件句柄外),但它返回的是被请求的字符串,而非打印出来。
 在“货币数字”中使用 sprintf
my $money = sprintf "%.2f",2.49997;
需要将所有有效的精度均保存在数字中,只是在输出时再进行四舍五入。

4、 高级排序
sort subroutine(排序子程序)
sub by_number {
if($a < $b){-1} elsif($a > $b){1} else {0}
}
my @result = sort by_number @some_numbers;
种三向的比较(three-way comparison)使用很频繁,太空船(spaceship)符号(<=>)
sub by_number {$a <=> $b }
cmp 操作符有些类似于字符串比较操作符如 ge

 依据值对 Hash 进行排序
:想根据 value 对 hash 排序。
sub by_socre { $score{$b} <=> $score{$a}}

 对多个 keys 排序
(发现两边的成绩相同)因为它比较这两个值得结果是 0。
my @winners = sort by_score_and_name keys %score;
sub by_score_and_name {
$score{$b} <=> $score{$a} #按照降序的成绩
or
$a cmp $b;  #字母顺序的名字
}

第十四章 进程管理
1、系统函数
最简单方法是使用 system 函数。
system "date";
system ' ls -l $HOME';
system "ls -l \$HOME";
注意有$时候的引号使用区别

system "long_running_command with parameters &";
它变成后台运行的进程

2、 避免 Shell
!system "rm -rf files_to_delete"or die "something went wrong";
这不是和系统调用相关的错误,因此 Perl 的$!变量不能描述。

3、exec 函数
system 函数创建子进程,它会立刻去执行请求的操作,Perl 则暂停。exec 函数引起 Perl 自己处理请求的操作。可以将它看作"goto"而非子程序调用。
实际使用 exec 的情况很少,除了和 fork 一起使用外
exec "date";
die "date couldn'trun: $!";

4、环境变量
在 Perl 中,环境变量可以通过 %ENV 这个 hash 变量得到,hash 中的每一个 key 代表一个环境变量。

5、使用反引号捕捉输出
my $now = `date`; #捕获 date 的输出
print "The time is now $now";  #已经有换行符
因此从安全和效率的观点,应当使用 system。
 在 List context 中使用反引号

6、 像文件句柄那样处理
open DATE, "date|"or die "cannot pipe from date: $!";
open MAIL, "|mail merlyn"or die "cannot pipe to mail: $!";
在第一个例子中, 竖线在右边,命令被调入,且其被打开到 DATE 这个文件句柄进行读入,这和 shell 中的命令date|your_program 类似。 
在第二个例子中,出现在左边,命令的标准输入被连接到 MAIL 这个文 件句柄, 这和命令your_program | mail merlyn 类似。

7、 发送和接收信号
my $int_count;
sub my_int_handler {$int_count++}
…
$int_count=0;
while(){
…某些处理花了几秒钟时间…
if ($int_count) {
#中断发生
print "[processing interrupted… ]\n";
last;
}
}

当每一行处理时,$int_count 的值可能是 0 如果没人按下 Ctrl-C,因此循环会继续处理下一行。但是,如果中断发生,则中
断处理部分会增加$count_int,当在结尾处检测到它时,循环退出。

第十五章 Perl模块
1、查找模块
从两种途径可以得到模块:Perl 发布包中附带的以及从 CPAN 中下载并安装的。
CAPN 上:http://search.cpan.org, 或 kobes 上:http://kobesearch.cpan.org查找。
方法之一是使用 perldoc 相应文档。
$perldoc CGI

2、 安装模块
如果模块使用了 MakeMaker,则需运行的命令大致如下:
$ perl Makerfile.PL
$ make install
如果在默认目录中不能安装,你可以针对 Makerfile.PL 使用 PREFIX 这个参数来指定目录。
$ perl Makerfile.PL PREFIX=/Users/fred/lib

一些模块的创建者使用另一个模块:Module::Build,来构造及安装他们的模块。此时的命令如下:
$ perl Build.PL
$./Build install

3、使用简单的模块
 File::Basename 模块
 用 命 令 perldocFile::Basename,或者你系统中的文档,可以阅读其功能
 use File::Basename;
 
 4、仅使用模块中的一些函数
假定需要在以前的程序中加入 File::Basename,同时你发现有一个子程序叫做:&dirname。
因此,你有一个子程序其名字和此模块中的一个函数同名
例如 File:Basename,在 use 声明中,可以使用输入列表(import list)来指定所需的函数,那它将只提供这些函数。
use File:Basename qw/ basename /;

use File:Basename qw/ /; #没有引入函数
my $betty = &dirname($wilma); #使用我们自己的子程序 &dirname(这里没有显示)
my $name = "/usr/local/bin/perl"; 
my $dirname = File::Basename::dirname $name; #使用模块中的 dirname

5、File::Spec 模块
将它和目录名一起组合成一个全文件名(fullfilename)。
use File::Spec;
#得到上面的$dirname, $basename 的值
my $new_name = File::Spec->catfile($dirname, $basename);

6、CGI.pm
创建 CGI 程序
CGI 模块提供了两种方法,一种是普通的老式函数接口,一种是 OO 接口。我们使用第一种。

7、数据库和 DBI
DBI(数据库接口(database interface))模块不是 Perl 默认附带的,但它是最常用的模块之一,因为大多数用户都需要连接到某种类型的数据库上。
DBI 漂亮的地方在于,对于绝大多数常用的数据库,其接口都是一样的,
当安装了 DBI 后,也需要安装 DBD(数据库驱动程序(database driver))。从 CPAN 上搜索 DBD,会返回一长串的结果。
根据数据库服务器,及其版本安装正确的数据库驱动程序。
use DBI;
$dbh = DBI->connect($data_source, $username, $password);

一旦连接上数据库后,则进入了 preparing, executing, reading 查询的循环。
当结束时,需要断开和数据库的连接。
$dbh->disconnect( );

Perl学习笔记四

作者:Ajian 发布时间:August 11, 2009 分类:Perl

前言:第十章是讲更多的控制结构方面,是之前的一个完善,第11和12章主要讲目录文件方面的操作,有SHELL基础的会发现很多都可以和SHELL中的一些命令对比,甚至是一样的。学习到12章这本书已经只有1/5了,再过4章就完结了,算是有个大概的了解的,最后一篇笔记就是最后四章了。

第十章 更多控制结构
1、unless 控制结构
在条件为假时执行 跟if 相反
也可以用unless ...else 但这种情况最好还是用if ... else

2、until 控制结构
跟while循环条件部分取反
until($j > $i){
$j *=2;
}
只是在条件为假时重复执行,而不是在条件为真的情况下执行。

3、表达式修饰符
print "$n is a negative number.\n" if $n<0;
简写的形式读起来很像英文:输出这段消息,如果$n 小于 0。
跟下面是一样的
if($n < 0){
print "$n is a negative number.\n";
}

4、The Naked Block 控制结构
裸块
{
body;
body;
body;
}

5、elsif语句
elsif,只有一个 e。

6、自增和自减
自增运算符(++)会使标量变量自动加1,这和 C 以及类似语言是一样的:
$bedrock++;  #$bedrock 的值加1;
自减运算符(--)将标量变量的值减

将++放在变量前,先将此变量增1,再取其值。这是前置++
my $m = 5;
my $n = ++$m;#$m 的值增加到6,将此值赋给$n
my $d = $m++; #$d 得到先前的值(5)然后自增到6
my $e = $m--; #$e 得到先前的值(6),再自减到5

7、for控制结构
for 循环的最常用用法是,进行重复的运算:
for($i =1; $i <=10; $i++){
print "I can count to $i;\n";
}
#从1到10

关键字 foreach 和 for 是等价的。

8、循环控制
last 操作
last 会立刻结束循环和C语言中的break类似
#输出所有出现 fred 的行,直到遇见 _ _END_ _标记
while(){
if(/_ _ END_ _/){
#这个标记之后不会有其它输入了
last;
}elsif(/fred/){
print;
}
}
##last 跳转到这里##
last 常用在最内层的循环体中,可以从中跳到外面来;

next 操作
它跳到当前循环块的最后面(块内)。next 之后,又会进入下一轮循环(这和 C 或者类似语言的 "continue"相似)

循环控制的第三个操作是 redo。它会调到当前循环块的顶端,不进行条件表达式判断以及接着本次循环。
next 和 redo 的最大区别在于,next 会进入下一次循环,而 redo 会继续执行本次循环。

9、 标签块
标签在 Perl 中就像一般标识符一样:由字母,数字,下划线组成,但不能由数字开头。
推荐标签均大写。这会防止标签和其它标识符冲突,同时也使之在代码中更突出。同时,标签很少使用,
LINE: while(<>){
oreach (split){
last LINE if /_ _END_ _/; #推出 Line 循环
…
}
}

10、 逻辑操作符
逻辑判断的逻辑与 AND(&&)和逻辑或 OR (||):

11、短路操作的值
短路操作的结果是最后被执行语句的返回值,而非仅仅是一个 Boolean 值。结果是相同的。如果最后被执行的部分为真,则整个为真;为假,则整个为假。

12、 三元操作符 ?:
三元操作有些像 if-then-else 一样,不过是在一个表达式之中。被称作“三元”操作符是因为它有三个操作数,看起来如下:
Express ? if_true_expr : if_false_expr

13、 控制结构:使用部分求值的操作符
前面三个操作符 &&, || , ?:,均有一个共同的特殊性质:根据左侧的值(true 或 false),来判断是否执行右侧代码。

第十一章 文件检验
1、文件检测操作
使用-e 选项
die "Oops! A file called '$filename' already exists.\n"
if -e $filename;

选项	含义
-r		文件或目录对此(有效的)用户(effective user)或组是可读的
-w		文件或目录对此(有效的)用户或组是可写的
-x		文件或目录对此(有效的)用户或组是可执行的
-o		文件或目录由本(有效的)用户所有
-R		文件或目录对此用户(real user)或组是可读的
-W		文件或目录对此用户或组是可写的
-X		文件或目录对此用户或组是可执行的
-O		文件或目录由本用户所有
-e		文件或目录名存在
-z		文件存在,大小为 0(目录恒为 false)
-s		文件或目录存在,大小大于 0(值为文件的大小,单位:字节)
-f		为普通文本
-d		为目录
-l		为符号链接
-S		为 socket
-p		为管道(Entry is a named pipe(a "fifo"))
-b		为 block-special 文件(如挂载磁盘)
-c		为 character-special 文件(如 I/O 设备)
-u		setuid 的文件或目录
-g		setgid 的文件或目录
-k		File or directory has the sticky bit set
-t		文件句柄为 TTY(系统函数 isatty()的返回结果;不能对文件名使用这个测试)
-T		文件有些像“文本”文件
-B		文件有些像“二进制”文件
-M		修改的时间(单位:天)
-A		访问的时间(单位:天)
-C		索引节点修改时间(单位:天)

2、 stat 和 lstat 函数
要得到文件的其余信息,可以使用 stat 函数,其返回 Unix 系统调用 stat 时相同的值
$dev 和 $ino
文件的设备号和索引节点号。
$mode
文件的权限位以及一些其它的位。
$nlink
文件或目录的(硬)连接数。
$uid 和 $gid
指文件所有权的 user ID 及 group ID。
$size
返回其大小,单位:字节,同 – 文件检测项相同。
$atime, $mtime, 及 $ctime
这三个时间,它们按照系统的时间格式:32 位
当 stat 的参数是符号连接时,其返回的信息是此符号连接指向的实体的信息,而非符号连接本身的信息,除非此符号连接所指向的内容不能被访问。
。如果需要得到(几乎是没用的)符号连接本身的信息,可以使用 lstat 代替 stat(它按照相同的顺序返回同样的值)。如果其操作数不是符号连接,则 lstat 和 stat 返回的值相同。

3、 localtime 函数
。gmtime 函数同 localtime 一样,除了其返回的形式为是世界时间(曾经被叫做格林威治时间)。如果想从系统中得到当前的时间,可使用 time 函数。localtime 和 gmtime 在默认的情况下都使用 time 的当前值,如果没提供参数:
my $now = gmtime; #得到当前的时间

4、位操作
按位与操作符(&)返回操作符左边和右边相应位操作的结果。
10 & 12 按位与;
10 | 12 按位或;
10 ^ 12按位异或;
6 << 2位左移,
25 >> 2位右移,
~10 位取反,

5、使用位串
所有的
使用特殊的下划线文件句柄

第十二章 目录操作
1、在目录树上移动
chdir改变工作目录 类似Shell的cd 命令
chdir "/etc" or die "cannot chdir to /etc: $!";

2、由于尖括号的含义可以指从文件句柄读入或 globbing,Perl 怎么判断使用哪一个操作呢?如果尖括号之间是一个严格意义
上的标识符,则其为文件句柄读入操作;否则,为 globbing 操作。如下例:
my @files = ; ##glob
my @lines = ; ##文件句柄读入
my $name = "FRED";
my @files = <$name/*> ##glob

3、目录句柄
从给定目录得到其文件名列表的方法还可以使用目录句柄(directory handle)
打开(使用 opendir 而非 open),从中读入(使用 readdir 而非 readline),关闭(使用 closedir 而非 close)
my $dir_to_process = "/etc";
opendir DH, $dir_to_process or die "Cannot open $dir_to_process: $!";
foreach $file(readdir DH) {
print "one file in $dir_to_process is $file\n";
}
closedir DH;
这些列表含有所有的文件名,包括点(.)文件,以及由点(.)开头,或点点(..)开头的文件名

readdir 操作返回的文件名没有路径名部分,而只是文件名。
得到的不是/etc/passwd 而是 passwd。

4、 递归的目录列表
 File::Find 的库,通过它你可以对递归的目录进行处理。
 
5、删除文件

在 Perl 中,我们使用 unlink:
unlink "slate","bedrock","lava"; 等价 $ rm slate bedrock lava
unlink glob "*.o";   等价  rm *.o 
返回值 如果数字为 3(个数),则它将所有的三个文件均删除了,如果为 0,则一个也没删除。

6、重命名文件
rename "old","new"; 类似Shell中的mv
甚至可以在不同的目录之间操作就跟mv的功能一样
怎样将所有的以.old 结尾的文件重名命名为以 .new 结尾的文件。
foreach my $file (glob "*.old"){
my $newfile = $file;
$newfile =~ s/\ .old$/.new/;
if (-e $newfile){
warn "can't rename $file to $newfile: $newfile exists\n";
}elsif(rename $file, $newfile){
##成功,什么也不做
} else {
warn "rename $file to $newfile failed: $!\n";
}
}

7、连接和文件
 符号连接。(也被叫做软连接(soft link),以区别于真或硬连接(hard links))是目录中的一种特殊实体
 link "chicken","egg" or warn "Can't link chicken to egg: $!"; shell 提示符后输入 ln chicken egg 的结果是差不多的。硬连接
 
 symlink "dodgson","carroll"or warn "Can't sysmlink Dodgson to carroll: $!";  shell 中使用 ln -s dodgson carroll 的结果是一样的。软连接
 可以使用 unlink 删除任意类型的连接。
 
8、 创建和删除目录
使用 mkdir 函数:
mkdir "fred",0755 or warn "Cannot make fred directory: $!";
要删除一个空的目录,按照类似于 unlink 函数的方法使用 rmdir 函数:
rmdir 在目录非空时失败。第一遍时,可以尝试使用 unlink 删除目录下的文件,其次再删除现在应当是空的目录。
my $temp_dir = "/tmp/scratch_$$"; #基于进程 ID
mkdir $temp_dir, 0700 or die "cannot create $temp_dir: $!";
#将$temp_dir 作为所有的临时文件存放的地方
unlink glob "$temp_dir/* $temp_dir/."; #将$temp_dir 里面的文件删掉
rmdir $temp_dir;  #将现在是空的目录删掉

9、修改权限
Perl 的 chomd 函数也能完成这种任务:
chmod 0755, "fred","barney";
Unix 的 chomd 命令可以使用的符号权限(如+x 或 go=u-w)对 chomd 函数是无效的 File::chmod 模块可以

10、改变所有者
my $user = 1004;
my $group = 100;
chown $user, $group, glob "*.o";

11、改变时间戳
my $now = time;
my $ago = $now -24*60*60;  #一天的秒数
utime $now, $ago, glob "*" #设成当前访问的,一天之前修改的


Perl学习笔记三

作者:Ajian 发布时间:August 10, 2009 分类:Perl

前言:这三章都讲的是有关正则表达式和他的使用,通过这三章也明白了很多在SHell或者在VIM中使用正则的一些来由,正则表达式是所有的语言中都有的,但又各有所细小的不同
并且在Perl中有很多特殊的 不错的应用。

第七章 正则表达式
1、不同的正则表达式的实现中,语法会有些微的不同
2、简单模式
要匹配某个模式(正则表达式)和$_的关系,可以将模式放在正斜线(//)之间,如下:
$_ = "yabba dabba doo";
if(/abba/){
  print "It  matched!\n";
}
表达式/abba/将在$_ 寻找这四个字母。如果找到,则返回 true
3、元字符
点(.)是通配符 它可以匹配任何单个的字符,
注意如果是显示句号,英文中跟通配符是一样的,所以这个时候用反斜线进行转义

星号(*)表示匹配前一项0次或者多次。

.* 将匹配任意字符任意多数。因为任意的字符串均能被匹配上(不包括换行符)。

加(+)的意思是可以匹配前面一项的一个或多个:/fred +barney/意思是 fred 和 barney 之间由空格分开,且只能是空格。(空格不是元字符)。
加(+)意指一个或多个,因此至少是一个。

问号(?),其含义是前面一个项出现一次,或者不出现。

括号(())用来表示分组。
例如,模式/fred+/能匹配上如 fredddddddd,这样的字符串,但这种字符串在实际中没有什么用途。
模式/(fred)+/能匹配上像 fredfredfred 这样的字符串

4、选择符
竖线(|),在这种用法中通常被读作"或(or)",意思是匹配左边的或者右边的。

5、字符类
字符类,是方括号[]中的一列字符,可以匹配上括号内出现的任意单个字符。它匹配一个字符,但这个字符可以是列中的
任意一个。
我们可以使用连字号(-)来表示某个范围的字母,因此上例也可以写做[a-cw-z]。

6、 字符类的简写
A、任何数字的类,[0-9],可以被简写为:\d。
B、\w 被称作 "word"字符:[A-Za-z0-9_]。由字母数字下划线组成。,\w 不能匹配单词,而只能匹配单个字符。为了匹配整个单词,需要后接加号。
C、\s 对于匹配空白(whitespace)将非常方便。它等价于[\f\t\n\r ] :格式符(form-feed)
;制表符(tab),换行符,回车,以及空格符

7、补集的简写
以使用[^\d], [^\w], 和[^\s],其含义分别是,非数字的字符,非 word(记住我们对 word 的定义)的字符,和非空白的字符。也可以使用它们对应的大写形式:\D, \W, \S 来完成。它们将匹配它们对应的小写形式不能匹配上的字符。

第八章 正则表达式的应用
1、使用m//匹配
放在一对正斜线(//)里面,如/fred/。这是 m//(模式匹配)的一种简写。同 qw//操作一样,可以使用任何
成对的分隔符。
可以使用 m(fred), m, m{fred}, m[fred],或者 m,fred,, m!fred!, m^fred^,其它非成对的分隔符也可以.
如果使用正斜线(/)作为分隔符,则可以省略掉前面的 m。
如果想写一个匹配 web URL 开头部分的模式,你可能使用/http:\/\//来匹配 http://。但如果使用 m%http://%将更易于阅读,书写,维护,以及调试。
记住,正斜线不是元字符,如果它不是分隔符,则不需在前面使用反斜线。

2、不区分大小写:/i
if(/yes/i) {#大小写无关
  print "In that case, I recommend that you go bowling.\n";
}

3、 匹配任何字符:/s
默认情况下,点(.)不匹配换行符,这对于"单行中查找"的问题能很好解决。如果你的字符串中有换行符,并希望点(.)能匹配它们,那可以使用/s 这个修饰符。

4、 添加空格:/x
由于/x 允许模式中使用空白,那么模式中的空格,制表符将被忽略。可以在空格前加上反斜线或者使用\t(许多方法中的一种),但匹配空白更常用的方法是使用\s(\s*或\s+)。
井号(#)表示后面是注释,如果需要匹配井号,可以使用\#或[#]。注意不要在注释中使用闭分隔符,否则将结束此模式匹配。
/
-? #可选的负号
\d+ #小数点前一个或多个十进制数字
\.? #可选的小数点
\d* #小数点后一些可选的十进制数字
/x #模式结束

5、如果在一个模式中需使用不止一个修饰符,可以一个接着一个。其顺序是不重要的。

6、锚定(anchors)则可以要求模式在特定的位置进行匹配。
符号^(脱字字符)表示在字符串的开头进行匹配,而符号$则表示在结尾想同时使用这两个锚定来确保匹配整个字符串。一个经常使用的例子是/^\s*$/,它将匹配一个空行(blank l)

7、词锚定
词界锚定,\b,是针对单词使用的。如/\bfred\b/可以匹配上单词 fred,但不能匹配 frederick,
非词界锚定为\B。它将在任何非\b 匹配的点上进行匹配。补集

8、 绑定操作符,=~
对$_进行匹配只是默认的行为,使用绑定操作符(=~)将告诉 Perl 将右边的模式在左边的字符串上进行匹配,而非对$_匹配。
my $some_other = "I dream of betty rubble.";
if($some_other =~ /\brub/){
  print "Aye, there's the rub.\n";
}

9、模式内可以进行内插 意思就是可以直接用变量

10、自动匹配变量 这里提到的三个变量名为: $&, $`, $'。
匹配上的那部分字符串将自动存储在$&之中。
匹配部分的前一部分存放在$`之中,后一部分被存到$'。另一种说法是,$`中含有正则表达式引擎在匹配成功前所找到的变量,而$'为此模式还没有匹配的剩余部分。如果将这三个变量放在一起,你将得到原始字符串:

11、已经见过三个数量词:*, +, ?。如果这三个数量词仍不能满足你的要求,那可以使用花括号({}),花括号中有 2 个数字,由逗号隔开,表示前面一项允许重复的次数。
模式/a{5,15}/将匹配 5 个到 15 个 a 中的任意一个(包括 5,和 15)

12、优先级
1.在此优先级表的最顶端是括号:(()),在分组和引用内存值的时候使用。括
2.第二级是数量词。这里有星号(*), 加号(+),问号(?)以及由花括号表示的数量词
3.第三级的是锚定和序列(sequence)。锚定包括(^) 表明字符串的开头,($)表明结尾,  (\b)词界符,(\B)非词界符。
4.优先级最低的是竖线(|),表示或。

第九章 使用正则表达式处理文件
1、 使用 s///进行替换"查询并替换"
s/Wilma/Betty/;#用 Wilma 替换 Betty

2、 使用/g 进行全局替换

3、可以使用其它的分隔符
s{fred}{barney};
s[fred](barney);
s#barney#;

4、替换操作中还可以使用/i, /x, 和 /s,这些在普通的模式匹配中已经出现过的修饰符。

5、同 m//一样,我们也可以通过使用绑定操作符改变 s///的替换目标:
$file_name =~ s#^.*###s;#将$file_name 中所有的 Unix 类型的路径去掉

6、大小写转换
\U 要求紧接着的均是大写:
\L 要求紧接着的均是小写

使用小写形式时(\l 和\u),只作用于下一个字符:

s/(fred|barney)/\U$1/gi;  #$_现在是 “ I saw BARNEY with FRED.”

7、使用正则表达式的操作是 split,它根据某个模式将字符串分割开。这对于由制表符分割开,冒号分割开,空白分割
开,或者任意字符分割开的数据是非常有用的
@fields = split /separtor/, $string;
这里有一条规则:开头的空元素会被返回,但结尾的空元素被丢弃◆

8、Join函数
join 函数不使用模式,但它完成同 split 相反的操作:split 将一个字符串分割开,而 join 函数将这些分割的部分组合成一个整体。join 函数类似于:
my $result = join $glue, @pieces;

my $x = join ":" , 4, 6, 8, 10, 12; #$x 为 "4:6:8:10:12"

9、更强大的正则表达式
A、 非贪婪的数量词
效率执行更高
回退(backtracking)操作更少
在原有的贪婪数量词后加问号就是非贪婪数量词
由于加号的非贪婪类型是 +?,星号的为 *?,你可能已经意识到剩下的两种数量词其对应的类型也是类似的。花括号的非贪婪类型看起来一样,只是在闭花括号后有一个问号,如{5,10}?或者{8,}?◆。甚至问号数量词也有非贪婪类型:??。它匹配一次或者 0 次,但倾向于匹配 0 次。

B、匹配多行文本
通常,正则表达式是针对单行文本的。
 但/m 这个正则表达式选项允许它们根据内部的换行符进行匹配。 (将m 看作多行(think m for multiple lines)。)

C、更新大量文件
命令行中
$perl –p –i.bak –w –e 's/Randall/Randal/g' fred*.dat

D、在开括号后面加上一个问号和冒号,(?:) ,其作用事告诉 Perl 括号只是分组的作用。



Perl学习笔记二

作者:Ajian 发布时间:August 9, 2009 分类:Perl

前言:最近也不知道为什么,总是缺少激情和动力,很快会好的,我的Perl学习计划,刚开始可不能半途而废,今天周六,突然狠下心半夜了也要解决三章。这三章完全跟前面三章的感觉不一样,前三章应该是很基础的,可能学每种语言都会遇到想类似的过程,而这三章则完全是Perl的特点,发现这本书还是挺不错的,他会解释每一个规则是如何来的,解释得跟这门语言一样自然,从这门语言也看到了其它语言的那些规定的符号的来源。

第四章 子程序

1、要定义自己的子程序,使用关键字 sub,子程序的名字(无&这个符号),组成子程序的缩进的代码块(花括号中)
sub marine {
$n + = 1; #全局变量$n
print "Hello, sailor number $n!\n";
}
2、子程序的定义可以在程序的任意位置
3、两个子程序有相同的名字,那后一个将覆盖前一个
4、使用子程序的名字(带有&)来调用子程序
5、返回值为最后一个被计算的表达式。
6、的警告信息 "a useless use of addition in a void context." 术语 void context 是说其值未被存于变量或者被别的方式使用。
7、将参数列表传给子程序中的方法是,在程序名后面接括号,括号内存放参数列表
$n = &max(10,15);#此子程序有 2 个参数
参数存放在@_这个变量中。
此子程序参数的第一个值存放在$_[0]中,第二个存放在$_[1],依次类推。

8、@_是子程序的一个私有变量
一个全局变量@_,它将在此子程序调用前存储起来,当子程序调用完成后,其早当将参数传递给子程序时不用担心它会影响此程序中其它子程序的@_这个变量的值。
子程序递归和嵌套调用时,每一次调用将得到新的@_,

9、默认情况下,Perl 中所有变量都是全局的;也就是说,这些变量可以在程序的任意部分使用。你也可以任意时候使用 my创建私有变量:
sub max {
my($m,$n);  		#新的,私有变量
($m,$n) = @_;  	#新的,私有变量
if($m > $n) {$m} else{$n}
}
在 if 代码块内部,其语句没有分号。通常仅当此代码块仅包含一条语句时才省略此分号。

10、将变量的作用域限制在一页,或者几行代码中,能加速开发和测试。

11、如果没有使用括号,my 仅定义一个变量
my ($num) = @_; #列表 context, 同($sum) = @_;
my $num = @_; #标量 context,同$num = @_;

12、Perl 是一种宽容的语言

13、告诉 Perl 进行更严格的语法检测,需要在程序顶端 use strict(或者在任意块或者文件中,如果你需要在此部分使用它):
use strict; #迫使采用更严格的检测

14、:如果子程序和 Perl 一个内嵌程序同名,则必须使用&来调用它。
,实际的使用规则是:除非知道 Perl 所有的内嵌函数,否则函数调用时都应当使用&。

第五章 输入输出
1、标准输入设备输入,使用,为行输入操作
chomp($line=)
行输入操作在到达文件的结尾时将返回 undef。对于从循环退出时非常方便。
while (defined($line = )) {
print "I saw $line";
}
不能将 chomp 操作插入条件表达式中.

2、另一种方法是使用尖括号输入(diamond operator):<>
尖括号操作(<>)是一种特殊的行输入操作。
while(<>){
chomp;
print "It was $_ that I saw!\n";
}
chomp 使用了默认参数,chomp 将对$_操作

3、标准输出  print 操作将传给它的依次输出到标准输出设备中,一个接着一个。
print @array; #打印出元素的列表 没有空格
print "@array"; #打印一个字符串(包含一个内插的数组) 由空格分开

print <>; # 'cat' 的源程序
print sort <>; #'sort' 的源程序

4、printf 函数有一个格式字符串(format string),后接需要输出的字符串列表。
格式字符串中有一些被称作格式符(conversion)的东西;每一个格式符由百分号(%)开头,由字母结束。
%d 为十进制整数
%s 是针对字符串的
%f 根据需要进行截尾
%% 要输出一个百分号
printf "%6f\n", 42;#输出为 ○ ○○○ 42(○此处指代空格)
如果宽度值为负数,则为左对齐(对于所有的格式符):
print "%-15s\n" , "flintstone" #输出为 flintstone○ ○○○

5、文件句柄(filehandle)是 Perl 程序 I/O 连接的名字,是 Perl 和外界的纽带
文件句柄的所有字母均大写
Perl 自身有六个文件句柄:STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT

Perl 再请求操作系统来建立同外部的连接。
open CONFIG, "dino";
open CONFIG, "fred";   #输出操作 输出内容到fred中
open LOG, ">>logfile";      #追加到logfile
注意空格:如果文件名前有空格,Perl 将忽略它。
Perl 5.6后
支持三种参数类型
open CONFIG, "<" , "dino";
open BEDROCK, ">" , $file_name;
open LOG, ">>" , &logfile_name();
增加安全性

6、关闭文件句柄
当结束一个文件句柄时,你可以如下这样关闭它:
close BEDROCK;
如果希望程序更加整洁,则每一个 open 都应当使用一个 close。
最好在不使用一个文件句柄时就立刻将它关闭,无论程序是否立即结束
关闭文件句柄将清空缓存,并释放文件的锁,由于可能有人会使用某个文件。

7、利用 die 函数来创建我们自己的严重错误。
die 函数将打印出你给它的消息(利用标准错误流),并确保程序退出时为非零(nonzero)的退出状态(exit status)
。
if(!open LOG, ">>logfile"){
die "Cannot create logfile:$!";
}
$!将告诉你原因
die 还会为你做一件事:他会自动将 Perl 程序的名字和行数输出在消息的末尾,因此能轻易的辨别出是哪一个 die 引起的错误。

8、warn 函数像 die 那样工作,除了最后一步,它不会从程序中退出。它也能加上程序的名字和行号,并把消息输出到标准错
误那里(standard error),和 die 一样。

9、写出(>)或追加的(>>)的文件句柄,可以和 print 或 printf 结合使用,如:
print LOG "Captain's log, stardate 3.14159\n";   #输出到 LOG 中
printf STDERR "%D percent complete.\n", $done/$total * 100;


第六章 哈希
1、哈希:是一种数据结构和数组类似,,可以将值存放到其中,或者从中取回值,其索引是名字而不像数组的数字 。
keys是唯一的字符串
2、keys 是唯一的,但 values 可以重复。hash 的 value 可以是数字,字符串,undef,或者它们的混合◆,但 key 是唯一的。
3、要访问 hash 元素,可以使用下面的语法:
$hashname{$some_key}

foreach $person (qw){
print "I've heard of $person $family_name{$person}.\n";
}

4、要引用整个 hash,使用百分号("%")作为前缀
5、这里有一条规则:最后一次赋值获胜。也就是说,列表中后面的元素将覆盖掉以前的元素(相同 key时)
6、使用大箭头号"=>"进行赋值
my %last_name=(
  "fred" => "flintstone",
  "dino" => undef,
  "barney" => "rubble"
  );
  
 7、keys 函数会返回此 hash 的所有 keys,values 函数将返回所有的 values。
 8、my %hash = ("a"=>1,"b"=>2,"c"=>3);
my @k = keys %hash;
my @v = values %hash;

Perl 并不维护 hash 中元素的顺序。

8、each函数:当对同一个 hash 函数进行一次迭代时,将返回下一个 key/value 对,直到所有的元素均被访问。e 对,则 each 函数将返回空表。
9、通常用法
很容易知道 hash 的某个元素是 true 还是 false,像下面这样:
if($books{$someone}){
print "$someone has at least one book checked out.\n";
}
10、要查看 hash 中是否存在某个 key(某人是否有借书卡)
,可以使用 exists 函数,如果 hash 中存在此 key,则返回 true,这是否有对应的 value 无关:
if(exists $books{$dino}){
print "Hey, there's a libaray card for dino!\n";
}

11、delete 函数将某个给定的 key(包括其对应的 value)从 hash 中删除。
(如果不存在这个 key,则什么也不做;不会有警告或者错误信息。)
my $person = "betty";
delete $books{$person}; #将$person 的借书卡删除掉

Perl学习笔记一

作者:Ajian 发布时间:July 31, 2009 分类:Perl

前言:实在是出于想看懂别人一些管理脚本,因为碰到大部分的PERL脚本,所以决定还是学一学这个语言,对他的评价可能也都是不一样,不管是好还是坏,是有前途还是没有前途,至于对于我现在的工作应该是很有用的。我是基于“Perl语言入门(第四版”进行的学习,我想学习语言还是脚踏实地,像我刚开始学习Shell一样,在什么都不知道的情况下,硬把一本电子书从头到尾都做了一遍笔记,也就入了shell的门。通过这次perl的学习,只要达到可以看懂那些perl脚本就行了,呵呵 至于是否会像书中说的“大多数 Perl 程序员推荐在写 Perl 程序时停止书写 shell, awk,C 程序”我就不知道了,到时真的爱上他也说不定。至于下面的笔记,就像以前在纸书上画标记一样记录下来,不要期望能从中得到什么更多更好的东西。对我应该会很有用,对于读者就不一定了。

Perl学习笔记一
Perl简介:Perl简单,几乎没有限制,速度快但有些丑。就像代表动物骆驼一样有些丑,但可以在艰苦的环境中完成任务。
CPAN简介: CPAN 是全面 Perl 归档网络(Comprehensive Perl Archive Network)的缩写。在 http://serach.cpan.org/ 和 http://kobesearch.cpan.org 上可以找到他们。
相关网站:
http://www.pm.org/
http://perldoc.perl.org
http://www.perldoc.org
http://faq.perl.org
邮件列表:http://lists.perl.org

1、简单例子
1)hello word程序
#!/usr/bin/perl
  print "Hello,word!\n";
第一行是#!行和程序的可移植性相关,需要找到每台机器的存放地点。如果有错 他的错误提示是“file not found”这个错误是SHELL提供的。

2)运行方法
./my_program
perl my_program

第二章 标量数据
1、Perl没有整数值,都视为双精度浮点来处理

2、指数的E大小写都可 -1.2E-23 -12e-24

3、61298040283768 允许用下划线分隔它 61_298_040_283_768

4、非十进制整数 八进制以 0 开头,十六进制以 0x 开头,二进制 0b 开头 十六进制中 A 到 F(或者 a 到 f)分别表示 10 到 15,同样可以用下划线分隔 0x1377_0B77   0x50_65_72_7C

5、数字操作符 Perl 除了提供通常的操作符 加(+),减(-),乘(*),除(/)等等之外:
模数运算符(%):10%3 的值是 10 除以 3 的余数
提供了和 FORTRAN 类似的指数操作符 :如 2**3,表示 2 的 3 次方,等于 8
通常不能进行一个负数的非整数次方的运算。

6、利用字符串(string)可以创建,遍历,操作二进制数据

7、单引号不是字符串的一部分, Perl 可以利用它来辨别字符串的开始和结束。反斜线(\)为转义字符。

8、如果想\和之后的字符成为转义字符(如\n 表示新行),应当使用双引号。

9、 双引号字符串中的转义符
符号                 含义
\n						换行
\r						回车
\t						制表符
\f						formfeed
\b						退格
\a						响铃
\e						escape(ASCII 中的 escape 字符)
\007					任何八进制值(这里是,007=bell(响铃))
\x7f					任何十六进制值(这里是,007=bell)
\cC						一个控制符(这里是,ctrl +c)
\\						反斜线
\”						双引号
\l						下个字符小写
\L						接着的字符均小写直到\E
\u						下个字符大写
\U						接着的字符均大写直到\E
\Q						在 non-word 字符前加上\,直到\E
\E						结束\L,\E 和\Q

10、字符串可由 . 操作符连接,(有点像PHP哦)
“hello”. “world”# 同于 “helloworld”

11、一个特殊的操作符是字符串重复操作符(string repetition operator),由小写的字母 x 表示。
“barney”x (4+1) #“barney”x 5, “barneybarneybarneybarneybarney”
复制次数(右操作数)在使用之前会把它转换为小于等于它的整数(如,4.8 变为 4)。

12、数字和字符串之间的自动转换  完全依赖于标量值之间的的操作符。
如果操作符(如+)需要数字,Perl 将把操作数当作数字看待。如果操作符需要字符串(如 . ),Perl 将把操作数当作字符串看待。
后面的非数字部分和前面的空格将被去掉,如 “12fred34”* “ 将给出 36
用首字符 0 表示非十进制值对数字有效,对自动转换没有作用。使用 hex()和 ort()来转换此类字符串。

13、$ perl -w my_program   -w警告参数
#!/usr/bin/perl -w 一直都需要警告(warning)在程序中添加

14、标量变量的名字由一个美圆符号($)后接 Perl 标识符:由字母或下划线开头,后接字母,数字,或者下划线,大小写是严格区分的。

15、标量变量在 Perl 中由$开头。在 shell 中,当取值时,需要$;赋新值时,不需要$。在 awk 和 C 中,完全不需要$。

16、大多数 Perl 程序中的变量都是小写的,应当选择能很好描述你的意图的变量名,仔细的使用下划线可以使变量名更易阅读和理解。

17、$barney= $barney*2;#将变量$barney 乘 2 再赋给$barney (40)

18、二元赋值  $fred+=5;  $barney*=3;
字符连接符号  $str = str .“ ” #$str 后接空格;
$str .= “”;#同上

19、print “ The answer is ”,6*7,“ .\n”; 利用逗号分开print输出

20、如果使用的是单独一个变量,是否使用引号没有影响。(跟SHELL是一样的)

21、在字符串中变量前($符号前)加上反斜线(\),变量将不会被内插(替换):
$fred = ‘hello’;
print “The name is \$fred .\n”;  #打印出美圆符号,变量不会被其值替换
print ‘The name is $fred’.“\n”; #同上

22、 perl中 shell 的分隔符:花括号({})  print “fred ate $n ${what}s.\n”;  #现在是使用变量$what 而不是$whats

23、操作符的优先级和结合性(由高到低)
结合性			操作符
左				括号和列表操作符的参数
左				->
				++ --(自增和自减)
右				**
右				\ ! ~ + - (一元操作符)
左				=~ !~
左				* / % x
左				+ - . (二元操作符)
左				<< >>
				Named unary operators (-X filetests, rand)
				< <= > >= lt le gt ge(“不等的”)
				= = != <=> eq ne cmp(“相等的”)
左				&
左				|^
左				&&
左				||
				..…
右				?:(三元操作符)
右				= += -= .=
左				, =>
				List operators(rightward)
右				not
左				And
左				or xor
如果记不住优先级时,可以使用括号。

24、数字和字符串的比较运算符
比较关系			数字			字符串
相等				==				eq
不等				!=				ne
小于				<				lt
大于				>				gt
小于或等于			<=				le
大于或等于			>=				ge

25、if控制结构 花括号是必须的
if($name gt 'fred'){
  print "'$name' comes after 'fred' in sorted order.\n";
}else{
  print "'$name' does not come after 'fred' .\n";
  print "Maybe it's the same string,in fact.\n";
}

26、Perl 不同于其它的一些语言,它没有 Boolean 类型。
1) 如果值为数字,0 是 false;其余为真
2)如果值为字符串,则空串('')为 false;其余为真
3)如果值的类型既不是数字又不是字符串,则将其转换为数字或字符串后再利用上述规则
字符串'0' 是唯一一个非空但值为 0 的串。
if(! $if_bigger){
}

27、如果想更多的控制输入,可以使用 Term::ReadLine 这个模块
$line = ;
if($line eq "\n" ){
}
28、基本上你的每一个程序都会用到它chomp
$text = "a line of text\n"; #也可以由输入
chomp($text);#去掉换行符(\n)。
常用方法:chomp ($text = ); #读入,但不含换行符

29、$betty = chomp $food; #得到值 1
 Perl 中的一条通用规则:除非移除它们时含义会变,否则括号是可以省略的。
如果结尾有两个或两个以上的换行符,chomp 仅去掉一个。如果没有,那什么也不做,返回 0。

30、while 控制结构
和 if 控制结构相同,花括号是必须的。

31、变量在第一次赋值前有一个特殊值 undef, undef 既非数字也非字符串,它是另一种标量类型。变量不进行初始化时、数字为0 字符串为空。

32、要分辨其是 undef 还是空串,可以使用 defined 函数,它将在为 undef 时返回 false,其余返回 true。
$madonna = ;
If ($defined ($madonna)){
print "The input was $madonna";
}else{
print "No input available!\n";
}

第三章 列表和数组
1、如果把标量认为是 Perl 中的单数的话,那列表(list)和数组则可认为是 Perl 中的复数。
2、列表是指数据,而数组是其变量名。列表中每一个元素都是一个独立的标量值。
3、perl哲学:没有不必要的限制。:最少含有 0 元素,最多可以填满你的可用内存。
4、数组索引编号从0开始$fred[0] ,同一程序也可以同时包含叫做$fred 的标量变量
5、下标可以是任何能返回数值的表达式。如果其值不为整数,则自动将其转换为小于它的最大整数值
如果下标超出了数组的范围,则其值为 undef。
6、将$#name 的值作为索引(下标)
7、列表最后一个逗号被忽略
8、(1 .. 5)  #同(1,2,3,4,5)  ..中的左值应小于右值,否则为空
(1.7 .. 5.7)#同上 小数取整数部分
9、 qw( 表示 "quoted words") 的方法可以不用输入大量的引号
("fred"," barney" ," betty","wilma","dino")
qw(fred barney betty wilma dino ) #同上,但输入更少
由于 qw 是一种引用,因此不可以在 qw 内添加注释。
 Perl 允许使用任何标点符号作为分界符  qw ! fred bar bet !   # #  { }  [ ] < >  这些符号都可以
 10、Perl 格言 : : 做一件事不只一种方法("There's More Than One Way To Do It")
 11、列表赋值
 ($fred, $barney, $dino) = ("flintstone", "rubble", undef);
左边列表中的每一个变量都得到了一个新值,和利用 3 个赋值语句得到的结果是一样的。
($fred, $barney) = ($barney, $fred) #交换两个变量
12、引用数组
在数组名前加@(后没有中括号)来引用整个数组。可以把他读作 "all of the(所有的)"
以@rocks 可以读作 "all of the rocks(所有的石头)"
@rocks = qw / bedrock slate lava /;
@copy = @quarry; #将一个数组中的值拷贝的另一个数组中
13、几种不使用索引来操作数组的方法
pop 操作将数组的最后一个元素取出并返回:
@array = 5..9;
$fred = pop(@array); #$fred 得到 9,@array 现在为(5,6,7,8)
如果数组为空,那 pop 什么也不做(因为没有元素可以移出),并返回 undef。

pop 相反的操作是 push,它可以将一个元素(或者一列元素)加在数组的末尾:
push(@array,0);#@array 现在为(5,6,0)
push @array,8;#@array 现在为(5,6,0,8)
push 的第一个参数或者 pop 的唯一参数必须是数组变量。

shift 和 unshift 操作:对一个数组的开头进行操作(数组的左端有最小下标的元素)
@array = qw# dino fred barney #;
$m = shift (@array);#$m 得到 "dino" @array 现在为("fred","barney")

14、数组也可以插入双引号的字符串中。
$email = "fred\@bedrock.edz"; #正确
$email = 'fred@bedrock.edu';  #另一种方法

15、foreach控制结构
foreach 从列表的第一个元素一直循环执行到
foreach $rock (qw/ bedrock slate lava /){
print "One rock is $rock.\n";
}
#打印出 3 种 rocks

16、 Perl 最常用的默认变量:$_
$_ = "Yabba dabba doo\n";
print;
#打印出默认变量$_。

17、 reverse 操作
reverse(逆转)操作将输入的一串列表(可能是数组)按相反的顺序返回。
@fred = 6 .. 10;
@barney = reverse (@fred); #得到 10,9,8,7,6

18、sort 操作
sort 操作将输入的一串列表(可能是数组)根据内部的字符顺序进行排序。
@rocks = sort @rocks;#现在@rocks 值是经过排序的

19、 标量和列表上下文(说是重中之重)
一个给定的表达式在不同的上下文中其含义是不同的。上下文是指表达式存在的地方.(有点像自然语言中的语言环境)
42 + something #something 必须是标量
sort something #something 必须是列表

@people = qw( fred barney betty );
@sorted = sort @people;  #列表 context:barney , betty, fred
$number = 42 + @people;  #标量 context:42+3,得到 45

@backwards = reverse qw / yabba dabba doo /;
#返回 doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo /;
#返回 oodabbadabbay

 在标量 Context 中使用 List-Producing 表达式
$fred = something; # 标量 context
@pebbles = something; #列表 context
($wilma,$betty) = something; #列表 context
($dino) = something; #列表 context 。括号是必须的,它使第四个区别于第一个。

在列表 Context 中使用 Scalar-Producing 表达式
其用法是显然的:如果一个表达式不是列表值,则标量值自动转换为一个元素的列表:
@wilma = undef;#OOPS!得到一个元素的列表(undef),不同于下面的例子
@betty = ();#将数组置空的正确方法
由于 undef 是一个标量值,将 undef 赋给数组不会清空数组。一个更好的方法是将空列表赋给它

20、在列表 Context 中
@lines = ; #将输入读入列表 context 中
当输入来源于一个文件时,它将读入文件的剩余部分。但如果输入来源于键盘,那文件结束符(end-of-file)是怎样输入的呢?
在 Unix 或者类似的系统中,包括 linux, Mac OS X,通常可以输入 CTRL +D来表明输入已经结束。Perl 会忽略这个字符,
因此它将在屏幕上显示出来。在 DOS/WINDOWS 系统中,使用 CTRL +Z。

chomp (@lines = ); #读入所有的行,不包括换行符