大于>gt如果$a大于$b返回真
小于或等于<=le如果$a不大于$b返回真
比较<=>cmp相等时为0,如果$a大为1如果$b大为-1
例子名字结果
-e$a存在如果在$a中命名的文件存在则为真
-r$a可读如果在$a中命名的文件可读则为真
-w$a可写如果在$a中命名的文件可写则为真
-d$a目录如果在$a中命名的文件是目录则为真
-f$a文件如果在$a中命名的文件是普通文件则为真
-T$a文本文件如果在$a中命名的文件是文本文件则为真名字ASCII定义代码
空白[\t\n\r\f]\s
词[a-zA-Z_0-9]\w
数字[0-9]\d还有一件你必须知道的事情,缺省时量词作用在它前面的单个字符上,因此/bam{2}/将匹配“bamm”而不是“bambam”。
如果你要对多于一个字符使用量词,你需要使用圆括弧,因此为了匹配“bambam”需要使用/(bam){2}/。
构造含义
$days简单标量值$days
$days[28]数组@days的第二十九个元素
$days{'Feb'}散列%days的“Feb”值
构造含义
${days}和$days一样,不过在字母数字前面不易混淆
$Dog:
:
days在Dog包里面的不同的$days变量
$#days数组@days的最后一个索引
$days->[28]$days一个引用指向的数组的第二十九个元素
$days[0][2]多维数组
$days{200}{'Feb'}多维散列
$days{2000,'Feb'}多维散列枚举
构造含义
@days包含($days[0],$days[1],...$days[n])的数组
@days[3,4,5]包含($days[3],$days[4],$days[5])数组片段的数组
@days[3..5]包含($days[3],$days[4],$days[5])数组片段的数组
@days{'Jan','Feb'}包含($days{'Jan'},$days{'Feb'})片段的散列
构造含义
%days(Jan=>31,Feb=>$leap?
29:
28,...)
代码含义
\n换行符(常作LF)
\r回车(常作CR)
\t水平制表符
\f进纸
\b退格
\a警报(响铃)
\eESC字符
\033八进制的ESC
\x7f十六进制DEL
\cCControl-C
\x{263a}Unicode(笑脸)
\N{NAME}命名字符
代码含义
\u强迫下一个字符为大写(Unicode里的“标题”)
\l强制下一个字符小写
\U强制后面所有字符大写
\L强制后面所有字符小写
\Q所有后面的非字母数字字符加反斜杠
\E结束\U,\L,或\Q。
常用通用含义替换
''q//文本字串否
""qq//文本字串是
``qx//执行命令是
()qw//单词数组否
//m//模式匹配是
s///s///模式替换是
y///tr///字符转换否
""qr//正则表达式是
#!
/usr/bin/perl
@lines=`perldoc–u–fatan2`;#反引号`通常在美式键盘数字1的左边。
不要和单引号‘混淆了
foreach(@lines){
s/\w<([^>]+)/\U$1/g;
print;
}
chomp()这个函数是去到\n的,如果两个\n只去掉一个。
pop是在数组的结尾,弹出
push是在数组的结尾,压入。
shift是在数组的开头,弹出
unshift是在数组的开头,压入reverse逆转
子程序返回值为最后一个被计算的表达式。
在if代码块内部,其语句没有分号。
Perl允许省略括号中最后一条语句的分号,在实际代码中,通常仅当此代码块仅包含一条语句时才省略此分号本书重点
my($num)=@_;#列表context,同($sum)=@_;此为特殊列表,表内只有一个变量
my$num=@_;#标量context,同$num=@_;
例如@_=qw(abcdefg)
还有补充就是($num)里得到的是值为a
$num里得到的是@_的个数为7记住,如果没有使用括号,my仅定义一个变量◆
my$first,$second没有定义$second
my($first,$second)两个都定义了.
$#name是name这个数组的最后一个索引
#@name是对数组name进行索引行输入操作在到达文件的结尾时将返回undef,这对于从循环退出时非常方便的
while(defined($line=)){
print"Isaw$line";
}
可简写
while(){
print"Isaw$_";
}在进行深入讨论前,我们要澄清一些事:
这种简写只在特定的情况下有效,默认的情况下不会将一行读入变量$_。
仅当while
循环的条件判断部分只包含行输入操作才有效◆。
如果在条件判断部分还有别的内容,则上述简写无效。
这是Unix中很少人知道的一个事实:
如许多标准的工具,如cat,sed,也使用这种约定,连接号(-)代表标准输入流。
如果在第二次使用<>之前重新初始化@ARGV,则能得到正确的结果
@ARGV是一个数组,但是好像是perl内定的一个数组.
如果需要更多的这种选项,那很可能你是使用模块按照标准方法处理它们。
参看Getopt:
:
Long和Getopt:
:
Std这两个模块,它们属发布的Perl中的一部分于标准print@array;#打印出元素的列表
print“@array”;#打印一个字符串(包含一个内插的数组)
第一个语句打印出所有的元素,一个接着一个,其中没有空格。
第二个打印出一个元素,它为@array的所有元素,其被存
在一个字符串中。
也就是说,打印出@array的所有元素,并由空格分开◆。
如果@array包含qw/fredbarneybetty/◆,则
第一个例子输出为:
fredbarneybetty,而第二个例子输出为fredbarneybetty(由空格分开)Perl在内插数组时,它会在元素之间加入空格。
如果字符串包含了换行符print@arrey;
如果字符串没有换行符print"@arrey\n";事实上,PerlPowerTools(PPT)项目的目标是将所有传统的Unix工具在Perl中实现,它们几乎实现了所有的工具(包括大多数的游戏),
当在如何实现shell时被难住了。
PPT项目是成功的,因为在大多数non-UNIX系统中实现了标准的Unix工具。
\d任意数字[0-9]
\D除数字外的任意字符[^0-9]
\w任意单词字符[_0-9a-zA-Z]
\W任意非单词字符[^_0-9a-zA-Z]
\s空白[\r\t\n\f]
\S非空白[^\r\t\n\f]
g匹配所有可能的模式
i忽略大小写
m将串视为多行
o只赋值一次
s将串视为单行
x忽略模式中的空白因此.*将匹配任意字符任意多数
但是.不匹配换行符
这里提到的三个变量名为:
$&,$`,$'
if(“Hellothere,neigbor”=~/\S(\w+),/){
print“Thatactuallymatched‘$&’.\n”;
}匹配的部分是“there,”(空格,单词,和一个逗号)。
变量$1中的值为there,而$&为整个被匹配的部分。
匹配部分的前一部分存放在$`之中,后一部分被存到$'。
另一种说法是,$`中含有正则表达式引擎在匹配成功前所找到的变
量,而$'为此模式还没有匹配的剩余部分。
如果将这三个变量放在一起,你将得到原始字符串:
if(“Hellothere,neighbor”=~/\S(\w+),/){
pirnt“Thatwas($`)($&)($’)”;
}
输出的消息为(Hello)(there,)(neighbor),为这三个自动匹配变量的值。
三个变量的值可能是空的,和之前数字匹配变量的例
子一样。
它们和数字匹配变量有相同的作用域。
通常,在下次成功匹配前其值不变。
现在,我们讨论我们之前说的“免费”问题。
是的,自由是要代价的。
这里的代价是,如果你使用了这三个自动匹配变量
中的任意一个,无论在程序的什么地方,其它地方的正则表达式的运行数度会变慢一些。
虽然,变慢的程度不大,但已经
足够让人担忧,因此许多Perl程序员从不使用这些自动匹配变量◆。
相反的,使用的替代的方法。
例如,如果需要使用$&,那么在整个模式上加上括号,并使用$1代替。
这些在替换中出现的大小写转换的修饰符,也可在双引号中使用:
print“Hello,\L\u$name\E,wouldyouliketoplayagame?
\n”;
默认时,split对$_操作,模式为空白:
my@fields=split;#同split/\s+/,$_;my@values=split/:
/,$x;#@values为(4,6,8,10,12)
my$z=join“-”,@values;#$z为“4-6-8-10-12”
split和join可以一起使用,但不要忘了join的第一个参数是字符串,而非模式我们将整个文件读入一个变量之中
openFILE,$filename
ordie“Can’topen‘$filename’:
$!
”;#如果打不开文件,出提示打不开的原因
my$lines=join'',;
$lines=~s/^/$filename:
/gm;这是?
号在正则表达式中的第四种用法:
问号,表示0或1的数量词,非贪婪修饰符,现在是开头符?
:
unless($mon=~/^Feb/){
print“Thismonthhasatleastthirtydays.\n”;
}else{
print“Doyouseewhat’sgoingonhere?
\n”;
}同下面if($mon=~/^Feb/){
print“Doyouseewhat’sgoingonhere?
\n”;
}else{
print“Thismonthhasatleastthirtydays.\n”;
}Pascal程序员应当小心:
在Pascal中,重复的until语句至少要执行一次迭代,但Perl中的until循环可能一次也不执行,如果循环执行前的条件表达式的值为真。
print“$nisanegativenumber.\n”if$n<0;
同下面
if($n<0){
print“$nisanegativenumber.\n”;
}还有一些其它的修饰语:
&error(“Invalidinput”)unless&valid($input);
$i*=2unitl$i>$j;
print“”,($n+=2)while$n<10;
&greet($_)foreach@person;Perl没有像C语言“switch”结构中的“fall-through(直接跳入)”下一个代码块的功能
for
这三个部分(初始化,条件判断,步长)的任意部分均能为空,但分号不能省略。
前面三个操作符&&,||,?
:
,均有一个共同的特殊性质:
根据左侧的值(true或false),来判断是否执行右侧代码。
&&表示,如果左面的值为真,则执行右侧的代码,
||表示左面的值为假时,则执行右侧的代码。
===================================================================
foreach(1..10){
print“Iterationnumber$_.\n\n”;
print“Pleasechoose:
last,next,redo,ornoneoftheabove?
”;
chomp(my$choice=);
print“\n”;
lastif$choice=~/last/i;
nextif$choice=~/next/i;
redoif$choice=~/redo/i;
print“Thatwas’tanyofthechoices…onward!
\n\n”;
}
print“That’sall,folks\n”;
============================================================
|文件检测选项及其含义|
============================================================检测选项含义
-r文件或目录对此(有效的)用户(effectiveuser)或组是可读的
-w文件或目录对此(有效的)用户或组是可写的
-x文件或目录对此(有效的)用户或组是可执行的
-o文件或目录由本(有效的)用户所有
-R文件或目录对此用户(realuser)或组是可读的
-W文件或目录对此用户或组是可写的
-X文件或目录对此用户或组是可执行的
-O文件或目录由本用户所有
-e文件或目录名存在
-z文件存在,大小为0(目录恒为false)
-s文件或目录存在,大小大于0(值为文件的大小,单位:
字节)
-f为普通文本
-d为目录
-l为符号链接
-S为socket
-p为管道(Entryisanamedpipe(a“fifo”))
-b为block-special文件(如挂载磁盘)
-c为character-special文件(如I/O设备)
-usetuid的文件或目录
-gsetgid的文件或目录
-kFileordirectoryhasthestickybitset
-t文件句柄为TTY(系统函数isatty()的返回结果;不能对文件名使用这个测试)
-T文件有些像“文本”文件
-B文件有些像“二进制”文件
-M修改的时间(单位:
天)
-A访问的时间(单位:
天)
-C索引节点修改时间(单位:
天)
=========================================================================
my@all_files=<*>;##基本上同@all_files=glob“*”一样;my@files=;##glob
my@lines=;##文件句柄读入
my$name=“FRED”;
my@files=<$name/*>##glob如果需要,可以使用readline得到间接文件句柄读入的操作my$name=“FRED”;
my@lines=readlineFRED;#从FRED读入
my@lines=readline$name;#从FRED读入(使用opendir而非open),从中读入(使用readdir而非readline),关闭(使用closedir而非close)。
不是读入文件的内容,而是将一个目录中的文件名(以及一些其它东西)读入,如下例:
my$dir_to_process=“/etc”;
opendirDH,$dir_to_processordie“Cannotopen$dir_to_process:
$!
”;
foreach$file(readdirDH){
print“onefilein$dir_to_processis$file\n”;
}
closedirDH;◆某些人知道rm通常会提示你是否删除这一类的文件。
但rm是一个命令,而unlink是系统调用。
系统调用从不询问权限,它们也从不道歉说自己错了。
◆这不是唯一的一个经常询问的问题;怎样一次将一批文件重命名是在这些新闻组中最常问的。
这也是在大多数新闻组的FAQ中,这通常
是第一个回答的问题。
直到现在,它仍然占据第一的位置。
foreachmy$file(glob“*.old”){
my$newfile=$file;
$newfile=~s/\.old$/.new/;
if(-e$newfile){
warn“can’trename$fileto$newfile:
$newfileexists\n”;
}elsif(rename$file,$newfile){
##成功,什么也不做
}else{
warn“rename$fileto$newfilefailed:
$!
\n”;
}
}要找出符号连接指向的地方,使用readlink函数。
它会告诉你符号连接指向的地方,如果参数不是符号连接其返回undef:
my$where=readlink“carroll”;#得到