更新记录:
- 2015/08/10 DonePage45
- 2015/08/11 DonePage68
- 2015/08/17 Read list and array, do a new one.
##前言杂记
- 适合管理员使用的语言
- Arvon’s读书笔记
- sixth edtion for learning perl
1
2
|
use 5.014;#该脚本需要在Perl 5.14或更高版本才能正常运行
perl -v#查看perl的版本
|
1
2
3
4
|
#!/usr/bin/perl
printf "Hello, world!\n";
use 5.010;
say "Hello, world!";
|
1
2
3
4
5
6
|
#!/usr/bin/perl
@lines = `perldoc -u -fatan2`;
foreach (@lines){
s/\w<([^>]+)>/\U$1/g;
print;
}
|
##标量数据
- 标量数据是Perl里面最简单的一种数据类型。对大部分标量来说,它要么是数字(如123或3.25e23),要
么是由字符组成的序列(如hello)。对Perl来说,数字和字符串大多情况下是可以在内部转换的。可以用操
作符对标量进行操作(如加法或字符串连接),产生的结果通常也是一个标量。标量可以存储在标量变量里,
也可以从文件和设备读取或写入这些位置。
###数字
####所有数字的内部格式都相同
- Perl内部,总是按“双精度浮点数(double-precision floating-point)”的要求来保存数字并进行运算
的。也就是说,Perl内部并不存在整数值–程序中用到的整数型常量会被转换成等效的浮点数值。
####浮点数直接量
- 直接量(literal)是指某个数字在Perl源代码中的写法。直接量并非运算结果,也不是I/O(输入/输出)
操作的结果,它只是直接键入源程序代码中的数据。
- Perl浮点数直接量的写法,小数点与前置的正负号都是可选的,数字后面也可以加上用“e”表示的10的次方
表示符(即指数表示法)。
- 如下列写法
1.25
255.000
255.0
7.25e45 #7.25乘以10的45次方,其中e可以大写
-6.5e123
####整数直接量
0
1234
-4321
41023789873 #可以写成41_023_789_873,Perl允许在整数直接量插入下划线,方便辨认
####非十进制的整数直接量
- Perl语言和其他许多程序语言一样,允许使用十进制(decimal)意外的其他进制表示数字。八进制(octal)
直接量以0开头,十六进制(hexadecimal)直接量以ox开头,二进制(binary)直接量以ob开头。十六进制的
A到F(可以写成小写的a到f,来代表十进制的10到15)。例如
o377 #八进制的377,等于十进制的255
0xff #十六进制的FF,等于十进制的255
ob11111111 #二进制的,等于十进制的255
- 这三个数字虽然看起来不同,但对Perl来说都是同一个数字
####数字操作符
- Perl提供了各种常见的数字操作符,如加、减、乘、除、取模、次方。例如:
2+3
5.1-2.4
3*12
14/2
10.2/0.3
10/3
10%3 #取模,结果为1
2**3 #次方,结果为8
###字符串
- 字符串就是一个字符序列,如hello。字符串可以各种字符任意组合而成。最短的字符串不包含任何字符,也
叫做空字符串。最长的字符串的长度没有限制。这符合Perl遵守的“无内置限制(nobuilt-inlimits)”的原则。
字符串通常是由可输出地字母、数字及标点符号组成,其范围介于ASCII编码的32到126之间。由于字符串可以
包含任何字符,所以可用它来创建、扫描或操控二进制数据,这是许多其他工具语言望尘莫及的。例如:你可以
将一个图形文件或编译过的可执行文件读进Perl的字符串变变量,修改它的内容再写回去。
- Perl完全支持Unicode,所以在字符串中可以使用任意一个合法的Unicode字符。不过由于Perl的历史原因
它不会自动将程序源代码当做Unicode编码的文本读入,所以如果你想要在源代码中使用Unicode书写直接量
的话,需手工加上utf8编译指令:
- 和数字一样,字符串也有直接量记法,也就是Perl程序中字符串的书写方式。包括单引号内的字符串和双引号
内的字符串。
####单引号内的字符串直接量
- 除了单引号和反斜线之外,单引号内所有的字符串都代表他们自己。
‘fred’
‘hello’
''
‘#$@%’
‘Don't let me go!’
‘the last character is a backslash:\’
‘'\’ #单引号后面紧接着反斜线
‘hi\n’ #单引号内的\n并不是换行符,而是表示字面上的两个字符
####双引号内的字符串直接量
“hi\n” #换行符
“love\tyou” #水平制表符
“\r” #回车
“\f” #换页符
“\b” #退格
“\e” #Esc(ASCII编码的转义字符)
“\cC” #控制符,就是COntrol键的代码(此例表示同时按下Ctrl和c键的返回码)
“\l” #将下个字母转换为小写
“\L” #将它后面的所有字母都转换为小写的,直到\E为止
“\u” #将下个字符转换为大写
“\U” #将它后面所有的字母都转换为大写,直到\E为止
“\E” #结束\L、\U和\Q开始的作用范围
####字符串操作符
“hello”.“world” #等同于”helloworld”
“hello” . ' ' . “world” #等同于’hello world'
‘hello world’ . “\n” #等同于"hello world\n"
注意
:链接运算符必须显示使用连接操作符(concatenation operator),而不是像其他一些语言
只需要把两个字符串放在一起就行。
特殊的重复操作符,小写字母x
,此操作符会将其左边的操作数与它本身重复连接,重复次数由右边的
操作数(某个数字)指定。例子:
“fred” x 3 #得到“fredfredfred”
“barney” x (4+1) #得到“barneybarneybarneybarneybarney”
5 x 4.8 #相当于5乘以4,它会把4.8当做4,因为这里是小写字母x而不是*
####数字与字符串之间的自动转换
- Perl根据操作符来确定你需要的是数字还是字符串。如操作符(比如+号)需要的是数字,Perl会将操作
数视为数字;在操作符(比如.)需要字符串时,Perl便会将数视为字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/usr/bin/perl
#Todo: concatenation operator
use 5.010;
printf "5*4.8\n";
printf 5 * 4.8 . "\n";
printf 5 x 4.8 . "\n";
printf "z" . 5*7 . "\n";
###Output
[root@Mo arvon_perl]# perl string_repetition
5*4.8
24
5555
z35
|
###Perl的内置警告信息
- 从Perl的5.6版本开始,可以通过编译指令开启警告功能
1
2
|
#!/usr/bin/perl
use warnings;
|
- 也可以在命令行上使用-w选项对要运行的程序开启警告功能
$ perl -w program.pl
- 如果看不懂某个警告信息,可以利用diagnostics这个编译命令报告更为详尽的问题描述。在perdiag文档
中列有简要警告信息和详细诊断说明,该文档时理解diagnostics输出信息的最佳参考:
1
2
|
#!/usr/bin/perl
use diagnostics; #会使程序变慢,如果熟悉,尽量不使用
|
###标量变量
- 变量(variable)就是存储一个或多个值的容器的名称。而标量变量就是单单存储一个值的变量。变量的
名称在整个程序中保持不变,但它所持有的值是可以在程序运行时不断修改变化的。
- 标量变量存储的是单个标量值。标量变量的名称是以$开头的,这个符号也称为魔符(sigil),然后是变
量Perl的标识符:由一个字母或下划线开头,后接多个字母、数字、下划线。标识符是区分大小写的:$Fred
和$fred是完全不同的变量。
$name
$Name
$NAME
$a_very_long_variable_that_ends_in_i
- Perl通过变量标识符的魔符来区分它是什么类型的变量。所以不管取什么名字,都不会和Perl自带的函数
或操作符的写法相冲突。$的确切意思是“取单个东西”或者“取标量”。
- 给变量取个好名字,例如:$my_name or $myName
###标量的赋值(assignment)
- 和其他程序语言差不多,Perl的赋值操作符为等号,等号的左边是变量名称,右边为某个表达式。
1
2
3
4
|
$fred = 17;
$barney = 'hello';
$barney = $fred+3;
$barney = $barney*2;
|
####双目赋值的操作符
1
2
3
|
$fred = $fred + 5; #相当于$fred += 5;
$barney = $barney * 3; #相当于$barney *= 3;
$str = $str. " "; #相当于$str .= "";
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/usr/bin/perl
$fred = 1;
$fred = $fred + 5;
printf "now + 5 fred is " . $fred . "\n";
$fred += 2;
printf "then + 2 fred is " . $fred . "\n";
$str = 'hello';
$str = $str . " ";
print "the string \$str is " . $str . "\n";
###Output
root@Mo arvon_perl]# perl double.pl
now + 5 fred is 6
then + 2 fred is 8
|
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/perl
$meal = "love";
$things = "arvon $meal mo";
print "$things\n";
$newThings = ' arvon ' . $meal . ' mo';
print 'now the $newThings is' . $newThings . "\n";
###Output[root@Mo arvon_perl]# perl varInsert.pl
arvon love mo
now the $newThings is arvon love mo
|
- 如果变量从未被赋值过,就会用空字符串来替换
- 如果只是打印这个变量值,则不必使用变量内插的方式:
1
2
|
print "$fred";
print $fred; #用这个比较好
|
- 可以直接键入一些字符的代码点(code point),再通过chr()函数转换成对应字符,反过来我们可以通过
ord()函数把字符转换为代码点
1
2
|
$alef = chr( 0x05Do );
$codePoint = ord('?');
|
###操作符的优先级与结合性
- 在复杂的表达式里,先执行哪个操作再执行哪个操作,取决于操作符的优先级。在Perl里乘法的优先级高于
加法,可以使用括号改变执行的优先级
- 当两个优先级相同的操作符抢着使用三个操作数时,优先级便交由结合性解决:
1
2
3
|
4 ** 3 ** 2 #4 ** (3 ** 2),得4 ** 9,向右结合
72 / 12 / 3#(72 / 12) / 3,得6 / 3,向左结合
36 / 6 * 3 #(36 / 6) * 3
|
###比较操作符
- perl的比较操作符类似于代数系统:<,<=,==,>=,>,!=。这些操作符的返回值要么是true要么是false。
- 字符串比较时,使用lt、le、eq、ge、gt、ne。
注意:
字符在ASCII编码中的顺序并不总是对应于字
符本身意义上的顺序。
##控制结构
###if控制结构
####例子
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/perl
#$name = 'fred';
$name = 'Nfred';
if ($name eq "fred"){
print "'$name' is 'fred' in\n";
}
else{
print "'$name' is not 'fred' is $name\n";
}
|
####布尔值
- 任何标量值都可以成为if控制结构里的判断条件。如果把表达式返回的真假值保存到变量中,那在判断时可以
直接检查该变量的值,读起来也方便:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/usr/bin/perl
#$name = 'fred';
$name = 'Nfred';
if ($name eq "fred"){
print "'$name' is 'fred' in\n";
}
else{
print "'$name' is not 'fred' is $name\n";
}
###Output
[root@Mo arvon_perl]# perl Boolean_value.pl
hello, world
|
- Perl和其他语言不同,Perl并没有专用的“布尔(boolean)”数据类型,它是靠一些简单的规则来判断的:
- 如果是数字,0为假,所有其他数字都为真
- 如果是字符串,空字符串('')为假;所有其他字符串为真。
- 如果既不是数字也不是字符串,那就先转换成数字或字符串再进行判断。
###获取用户输入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/usr/bin/perl
print "Input something please: ";
$line = <STDIN>;
if ($line eq "\n"){
print "That was just a blank line!\n";
}
else{
print "That line of input was: $line";
}
###Output
[root@Mo arvon_perl]# perl stdin01.pl
Input something please:
That was just a blank line!
[root@Mo arvon_perl]# perl stdin01.pl ]
Input something please: hello
That line of input was: hello
|
###chomp操作符
- chomp()操作符只能用于单个变量,且该变量的内容必须为字符串,如果该字符串的末尾是换行符,chomp()
的任务就是去掉它。
1
2
3
4
5
6
7
8
|
#!/usr/bin/perl
$text = "a line of text\n"; #or input by <STDIN>
chomp($text); #remove the \n
print $text;
###Output
[root@Mo arvon_perl]# perl chompTraining.pl
a line of text[root@Mo arvon_perl]#
|
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/perl
chomp($text = <STDIN>); #读入文字,略过最后的换行符
#$text = <STDIN>; #等同于上面的写法
#chomp($text):
print $text;
###Output
[root@Mo arvon_perl]# perl chompTraining02.pl
hello,world
hello,world[root@Mo arvon_perl]#
|
###while控制结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/usr/bin/perl
$count = 0;
while ($count < 10){
$count += 2;
print "Now the number is $count\n";
}
###Output
[root@Mo arvon_perl]# perl whileCount.pl
Now the number is 2
Now the number is 4
Now the number is 6
Now the number is 8
Now the number is 10
|
###undef值
- 我们未赋值时就用到了某个不存在标量变量,并不会让程序停止运行,当成数字使用,它会表现的像0;当
做字符串使用,它会表现的像空字符串。
1
2
3
4
5
6
7
8
9
10
11
12
|
#!/usr/bin/perl
#累加奇数
$n = 1;
while ($n < 10){
$sum += $n;
$n += 2;#准备奇数
}
print "The total was $sum.\n"
###Output
[root@Mo arvon_perl]# perl accumulation.pl
The total was 25.
|
###definded函数
- 行输入操作符有时候会返回undef。要判断某个字符串是undef而不是空字符串,可以使用defined
函数。如果是undef,该函数返回假,否则返回真:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/usr/bin/perl
$madonna = <STDIN>;
if (defined($madonna)){
print "The input was $madonna";
}
else{
print "No input available\n";
}
#$madonna = undef;
###Output
[root@Mo arvon_perl]# perl undef01.pl
No input available
[root@Mo arvon_perl]# perl undef01.pl
Mo
The input was Mo
[root@Mo arvon_perl]# perl undef01.pl
The input was
|
##列表和数组
- 如果Perl的标量代表单数(singular),那么列表和数组就表示复数(plural)。
- 列表(list)是标量的有序集合,而数组(array)则是存储列表的变量。列表指的是数据,而数组指的是变
量。列表里的值不一定放在数组里,但每个数组变量都包含一个列表(即便是不含任何元素的空列表。
- 数组或列表中的每个元素 (element)都是单独的标量变量,拥有独立的标量值。这些值是有序的,从开始到
终止元素的先后次序是固定的。
###访问数组中的元素
1
2
3
4
5
6
7
8
9
10
11
|
#!/usr/bin/perl
use 5.010;
#print "Hello world\n";
$fred[0] = "Hello";
$fred[1] = "My";
$fred[2] = "Name";
print "$fred[0]\n";
###Output
>arvon@Mo:~/arvon_perl> perl array.pl
Hello
|
###特殊的数字索引
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#!/usr/bin/perl
use 5.010;
$rocks[0] = 'hello';
$rocks[1] = 'list';
$rocks[2] = 'array';
$rocks[3] = 'element';
$rocks[4] = 'four';
$rocks[9] = 'nine';
#
$end = $#rocks;
print "\$end is $end\n";
#
$number_of_rocks = $end + 1;
print "The number is $number_of_rocks\n";
#
$rocks[ $#rocks ] = 'hard rodk';
###Output
arvon@Mo:~/arvon_perl> perl array_print.pl
$end is 9
The number is 10
|
###列表直接量
- 列表直接量(list literal),可以由圆括号内用逗号隔开的一组数据表示,而这些数据就称为元素。
for example
1
2
3
4
5
6
7
8
|
(1, 2, 3) #(1, 2, 3,)相同的逗号会被忽略
("fred", 4.5) #两个元素,'fred'和4.5
() #空列表,0个元素
(1..100) #100个整数组成的列表
(1..5) #..是范围操作符(range operator)
(1.7..5.7) #同上,但两个数字的小数部分会被去掉
(5..1) #表示空列表,只能正向计数
($m..$n) #由$m和$n决定
|
###qw简写
- 在perl程序中,经常会需要建立简单的单词列表。使用qw简写,可以省去键入的引号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#!/usr/bin/perl
use 5.010;
("Mo", "have", "rose", "you", "known");
#
qw( Mo have rose you known );
#
qw(Mo
hava rose
you known);
#
qw(
Mo
have
rose
you
known
);
#
qw! Mo have rose you known!;
qw/ Mo have rose you known/;
qw# Mo have rose you known#;
|
###列表的赋值
1
2
3
4
|
#!/usr/bin/perl
use 5.010;
($fred, $barney, $dino) = ("flintstone", "rubble", undef);
#左侧列表中的三个变量会依次被赋予右侧列表中对应的值,相当于分别做了三次独立的赋值操作;
|
###pop和push操作符
- 要增加元素到数组尾端时,只要将它存放到更高索引的新位置就可以了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#!/usr/bin/perl
@array = 5..9;
$mo = pop(@array);
printf "now \$mo is $mo\n";
$arvon = pop(@array);
printf "now \$arvon is $arvon\n";
push(@array, 0);
printf "now \@array is @array\n";
push@array,3;
printf "now \@array is @array\n";
push@array,"Hello";
printf "now \@array is @array\n";
@newOne = qw/ my name is arvon /;
print "@newOne\n";
###Output
arvon@Mo:~/arvon_perl> perl assignment_array.pl
now $mo is 9
now $arvon is 8
now @array is 5 6 7 0
now @array is 5 6 7 0 3
now @array is 5 6 7 0 3 Hello
my name is arvon
|
###shift和unshift操作符
- 相反,unshift和shift操作符是对数组的开头进行处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#!/usr/bin/perl
use 5.010;
@array = qw/ why are you so diao /;
$one = shift@array;#$one is "why", @array = are you so diao
print "$one is not @array\n";
$two = shift(@array);#$two is "are", @array = you so diao
print "$two is not @array\n";
$three = shift@array;#$three is "you", @array= so diao
print "$three is not @array\n";
##
unshift(@array, 4);
print "Now \@array is @array\n";
unshift(@array, 5);
print "Now \@array is @array\n";
@others = 1..3;
unshift @array, @others; #@array变成了(1, 2, 3, 4, 5, )
print "\@others is @others, But now \@array is already @array";
###Output
arvon@Mo:~/arvon_perl> perl unshift_str.pl
why is not are you so diao
are is not you so diao
you is not so diao
Now @array is 4 so diao
Now @array is 5 4 so diao
@others is 1 2 3, But now @array is already 1 2 3 5 4 so diao
|
###splice操作符
- push-pop和shift-unshift操作符都是对数组首尾进行操作的,中间的话就用splice
- Example one
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/usr/bin/perl
use 5.010;
@array = qw( pebbles dino fred barney betty );
@removed = splice @array, 2;#在原来的数组中删掉fred及其后的元素
#@removed变成qw(fred barney betty)
#而原来的@array则变成qw(pebbles dino)
print "\@array now is @array\n";
print "\@removed is @removed\n";
###Output
arvon@Mo:~/arvon_perl> perl splice_string.pl
@array now is pebbles dino
@removed is fred barney betty
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/usr/bin/perl
use 5.010;
@array = qw( pebbles dino fred barney betty );
#@removed = splice @array, 2;#在原来的数组中删掉fred及其后的元素
##@removed变成qw(fred barney betty)
##而原来的@array则变成qw(pebbles dino)
#print "\@array now is @array\n";
#print "\@removed is @removed\n";
#@removed = splice @array, 1, 2;
##This time @removed is (pebbles, barney, betty )
@removed = splice @array, 1, 0, qw(wilema);
##Just known @array is became (pebbles wilema dino fred barney betty)
print "now \@removed is @removed, and \@array is @array.\n"
###Output
arvon@Mo:~/arvon_perl> perl splice_string.pl
now @removed is , and @array is pebbles wilema dino fred barney betty.
|
###字符串的内插
- 和标量一样,数组的内容同样可以被内插到双引号中。内插时,会在数组的各个元素之间自动添加分隔用的空格
1
2
3
4
5
6
7
8
|
#!/usr/bin/perl
use 5.010;
@rocks = qw/ flintstone slate rubble /;
print "Quartz @rocks limestone\n"
###Output
arvon@Mo:~/arvon_perl> perl array_one.pl
Quartz flintstone slate rubble limestone
|
- Example for index_expression
1
2
3
4
5
6
7
8
|
#!/usr/bin/perl
use 5.010;
@fred = qw(eating rocks is wrong);
$fred = "right";
print "This is $fred[3]\n"; #just right
print "This is ${fred}[3]\n"; #wrong
print "This is $fred"."[3]\n"; #wrong
print "This is $fred\[3]\n"; #still wrong
|
##后续下一篇,太长了不方便查阅