perl语言linux培训,linux-Perl-语言入门

这篇博客介绍了Perl编程语言的基础知识,包括变量、运算符、控制结构、输入输出、数组和哈希的使用。文章通过示例展示了如何编写简单的Perl程序,如打印“Hello, world!”,以及处理字符串、数字和数组的方法。此外,还提到了子程序的定义和调用,以及文件输入输出操作。
摘要由CSDN通过智能技术生成

http://jianlee.ylinux.org/Computer/Perl/perl_base.html

1,第一个Perl程序

Perl的发明人:Larry Wall。

Perl”,指语言本身;“perl”,指程序运行的解释器。

#!/usr/local/bin/perl -w

print "Hello,world!/n";

在Unix系统中,如果文本的第一行前两个字符是“#!”,接着的就是执行下面文件的程序。perl在你的系统的哪里,可以用which 或者whereis来查找。一般都在/usr/bin/perl或者/usr/local/bin/perl这两个地方。-w表示开启警告。

1.1 Perl 内嵌的警告 使用 -w 参数可以打开警告:

$ perl -w perl程序   # 命令行执行警告

#!/usr/bin/perl -w  # 源代码中使用警告

1.2 Perl特殊的地方

Perl通常允许使用任意数量的空白(如空格,制表符,换行符)来使程序易于阅读。

Perl中没有“main”程序。

Perl中不需要声明变量。

Perl严格区分大小写。

Perl中的括号可以省略。

Perl中所有数字内部的格式都是双精度浮点数。

2,语法

2.1 标量

标量是 Perl 中最简单的数据类型。大多数的标量是数字(如 255 或 3.25e20)或 者字符串(如 “hello”)。

2.1.1 数字

perl中所有数字内部的格式都是双精度浮点数。程序中的整数被当做等价的浮点数来处理。

浮点数

1.25

-12e-24 #- -12x10 的-24 次方(很小的负数)

-1.2E-23 #指数符号可以大写(E)

整数

-40

61298040283768#为方便阅读可作:61_298_040_283_768

非十进制整数

0377     #八进制数字 377,等同于十进制数字 255

0xff       #十六进制数字 FF,等同于十进制数字 255

0b11111111 #等同于十进制数字 255

数字操作符

2+3       #2+3,5

5.1-2.4   #5.1-2.4,2.7

3*12      #3*12,36

14/2      #14/2,7

10.2/0.3  #10.2/0.3,34

10/3      #通常是浮点除,3.33333... ...

2.1.2 字符串

Perl能计算长度,不用靠null来判断字符串是否结束。

单引号字符串

'fred' #四个字符:f,r,e,d

'' #空字符(没有字符)

'hello\n'

'\'\\' #单引号(')跟着反斜线(\)字符串

单引号中的 "\n" 不会被当作换行符来处理。

双引号字符串

"barney"         #等同于 'barney'

"hello world\n"  #hello world,换行

2.1.3 变量

变量由符号($)后接 Perl 标识符构成。Perl大小写是严格区分的:变量$Fred 和变量$fred是不同的。

$fred = 17;

$barney = "hello";

2.1.4 Boolean 值 perl 没有专门的 Boolean 值, 真假值这样判断:

如果值为数字,0 是 false;其余为真

如果值为字符串,则空串(‘)为 false;其余为真

如果值的类型既不是数字又不是字符串,则将其转换为数字或字符串后再利用上述规则

这些规则中有一个特殊的地方。由于字符串'0' 和数字 0 有相同的标量值,Perl 将它们相同看待。也就是说字符串 '0' 是唯一一个非空但值为 0 的串。

2.1.5 undef 值 一种值。变量被赋值之前使用它会有什么情况发生呢?通常不会有什么严重的后果。变量在 第一次赋值前有一个特殊值 undef, 按照 Perl 来说就是:"这里什么也没有,请继续"。如果这里的“什么也没有”是一些“数字”,则表现为 0。如果是“字符串”,则表 现为空串。但 undef 既非数字也非字符串,它是另一种标量类型。

defined 函数 能返回 undef 的操作之一是行输入操作,。通常,它会返回文本中的一行。 但如果没有更多的输入,如到了文件的结尾,则返回 undef。要分辨其是 undef 还是空串,可以使用 defined 函数, ,如果其参数是 undef 值就返回 false,其他 值返回 true。

$madonna = ;

If ($defined ($madonna)){

print "The input was $madonna";

} else {

print "No input available!\n;

}如果想声明自己的 undef 值,可以使用 undef:

$madonna = undef ; #同$madonna 从未被初始化一样。

2.2 操作符

2.2.1 字符串操作符

链接操作符 "."

"hello"."world"     # 同于 "helloworld"

"hello".''."world"  # 同于 "hello world"

'hello world'."\n"  # 同于 "hello world\n"

重复操作符 "x"

"fred" x 3   # "fredfredfred"

5 x 4        # 等于 "5" x 4, "5555"

2.2.2 数字和字符串之间的自动转换 大多数情况下,Perl 将在需要的时候自动在数字和字符串之间转换。且完全依赖于标量值之间的的操作符。 如果操作符(如+)需要数字,Perl 将把操作数当作数字看待。如果操作符需要字符 串(如 . ), Perl 将把操作数当作字符串看待。

"12" * "3"  # * 操作符需要数字,所以结果为 36

"12fred34" * " 3" # 结果仍然是 36 , 后面的非数字部分和前面的空格都过滤掉。

"Z" . 5 * 7 # 等于 "Z".35, 或 "Z35"

2.2.3 二元赋值操作符

$fred+=5;

$barney*=3;

$str .= "";

2.2.4 数字和字符串比较操作符

比较关系数字字符串相等== eq不相等!=ne小于gt小于等于<=le大于等于>=ge

2.3 控制结构

2.3.1 if 控制结构

if ($name gt 'fred') {

print "$name’comes after 'fred' in sorted order.\n";

}

2.3.2 while 控制结构

$count = 0;

while ($count < 10) {

$count + = 2;

print "count is now $count\n";

}

2.4 输入输出

2.4.1 print 输出

print "hello world\n";   #输出 hello world,后接换行符

print "The answer is", 6*7, ".\n"; #其实是列表【变量内插】字符串中引用标量变量。变量内插通常也叫做双引号内插,因为它在双引号中(而非单引号)才有效。

$meal = "brontosaurus steak" ;

$barney = "fred ate a $meal";

$barney = 'fred ate a'.$meal;    # 同上

$fred =‘hello’;

print“The name is\$fred .\n”; #打印出美圆符号,变量不会被其值替换

print‘The name is $fred’. “\n”; #同上

【使用花括号】

$what =“brontosaurus steak”;

$n = 3;

print“fred ate $n $whats.\n”; #不是steaks,而是$whats的值

print“fred ate $n ${what}s.\n”; #现在是使用变量$what

print“fred ate $n $what”. “s.\n”; #另一种方法

print‘fred ate ’. $n . ‘’. $what . “s.\n”; #一种复杂的方法

2.4.2 用户的输入 chomp 操作

$text = "a line of text\n";    # 也可以由输入

chomp($text);                 #去掉换行符(\n)。一步执行:

chomp ($text = ); #读入,但不含换行符chomp 是一个函数。作为一个函数,它有一个返回值,为移除的字符的个数。这个数字基本上没什么用:

$food = ;

$betty = chomp $food; #得到值 1

如上,在使用 chomp 时,可以使用或不使用括号()。这又是 Perl 中的一条通用规则:除非移除它们时含义会变,否则括号是可以省略的。

2.5 列表和数组

#!/usr/bin/env perl -w

$fred[0] = "yabba";

$fred[1] = "dabba";

$fred[2] = "doo";

print @fred;

#print @fred."\n";

2.5.1 qw 简写

#对于列表(“fred”, “barney”, “betty”, “wilma”, “dino”)

qw(  fred barney betty wilma dino ) #同上,但输入更少

qw ! fred barney betty wilma dino !

qw#  fred barney betty wilma dino # #有些像注释

2.5.2 列表赋值

($fred, $barney, $dino) = ("flintstone", "rubble", undef);

($fred, $barney) = qw ; #两个值被忽略了

($rocks[0],$rocks[1],$rocks[2],$rocks[3]) = qw/talc mica feldspar quartz/;当想引用这个数组时, Perl 有一种简单的写法。在数组名前加@(后没有中括号) 来引用整个数组。 你可以把他读作 "all of the "(所有的)”,所以@rocks 可以 读作 "all of the rocks(所有的石头)"。其在赋值运算符左右均有效:

@rocks = qw / bedrock slate lava /;

@tiny = ();                         #空表

@giant = 1..1e5;               #包含 100,000 个元素的表

@stuff = (@giant, undef, @giant);      #包含 200,001 个元素的表

@dino = "granite";

@quarry = (@rocks, "crushed rock", @tiny, $dino);

2.5.3 pop 和 push 操作

@array = 5..9;

$fred = pop(@array);      #$fred 得到 9,@array 现在为(5,6,7,8)

$barney = pop @array;   #$barney gets 8, @array 现在为(5,6,7)

pop @array;                   #@array 现在为(5,6)(7 被丢弃了)

push(@array,0);                   #@array 现在为(5,6,0)

push @array,8;                    #@array 现在为(5,6,0,8)

push @array,1..10;              #@array 现在多了 10 个元素

@others =qw/9 0 2 1 0 /;

push @array,@others;          #@array 现在又多了 5 个元素(共有 19 个)

2.5.4 shift 和 unshift 操作 push 和 pop 对数组的末尾进行操作(或者说数组右边有最大下标的元素,这依赖 于你是怎样思考的)。相应的, unshift 和 shift 对一个数组的开头进行操作(数 组的左端有最小下标的元素) 。下面是一些例子:

@array = qw# dino fred barney #;

$m = shift (@array);       #$m 得到 "dino", @array 现在为 ("fred", "barney")

$n = shift @array;          #$n 得到 "fred", @array 现在为 ("barney")

shift @array;                  #@array 现在为空

$o = shift @array;          #$o 得到 undef, @arry 仍为空

unshift(@array,5);          #@array 现在为(5)

unshift @array,4;           #@array 现在为(4,5)

@others = 1..3;

unshift @array, @others;  #array 现在为(1,2,3,4,5)和 pop 类似,如果其数组变量为空,则返回 undef。

2.5.5 字符串中引用数组 和标量类似,数组也可以插入双引号的字符串中。插入的数组元素会自动由空格分 开:

@rocks = qw{ flintstone slate rubble };

print "quartz @rocks limestone\n";        #输出为 5 种 rocks 由空格分开

2.5.6 foreach 控制结构

foreach $rock (qw/ bedrock slate lava /) {

print "One rock is $rock.\n" ;           #打印出 3 种 rocks

}这里的$rock不是这些列表元素中的一个拷贝而是这些元素本身

2.5.7 最常用的默认变量 : $_ 如果在 foreach 循环中省略了控制变量,那 Perl 会使用其默认的变量:$_。除了 其不寻常的名字外,这和普通变量类似,如下面代码所示:

foreach(1..10){                 #使用默认的变量$_

print "I can count to $_!\n";

}

$_ = "Yabba dabba doo\n";

print;                                      # 打印出默认变量 $_

2.5.8 reverse 操作 reverse(逆转)操作将输入的一串列表(可能是数组)按相反的顺序返回。

@fred = 6 .. 10;

@barney = reverse (@fred);  #得到 10,9,8,7,6

@wilma = reverse 6 . .10;   #同上,没有使用额外的数组

@fred = reverse @fred;     #将逆转过的字符串存回去

2.5.9 sort 操作

@rocks = qw/ bedrock slate rubble granite /;

@sorted = sort(@rocks);                      #得到 bedrock, granite, rubble, slate

2.6 子程序

子程序(本章中若无特殊说明,子程序均指subroutine,译者注)的定义可以在程序的任意位置。

2.6.1 使用 sub 定义子程序

sub marine {

$n + = 1; #全局变量$n

print "Hello, sailor number $n!\n";

}

2.6.2 调用子程序

&marine; #输出 Hello, sailor number 1!

&marine; #输出 Hello, sailor number 2!由于所有的被调用的子程序都要返回值,因此使用特殊的返回值语法在大多数情况下是一种浪费。因此Larry 将之简化了。

当Perl 遍历此子程序时,将会计算每一步的值。此子程序中最后计算的值将被返回。注意,“The last expression evaluated”的含义是指最后一个被求值的表达式,而非程序的最后一行。

2.6.3 参数

$n = &max(10,15);     # 此子程序有 2 个参数此参数列表被传到子程序中;这些参数可以被子程序使用。当然,这些参数存放在某个地方,在 Perl 中,会自动将此参数列表(此参数列表的另一个名字)自动存放在 一个叫做@_的数组中。子程序可以访问次数组变量来确定此参数的个数以及其值。 这也就是说此子程序参数的第一个值存放在$_[0]中,第二个存放在$_[1],依次类 推。但必须强调的是这些变量和 $_ 这个变量没有任何关系,如$dino3(数组 @dino 的一个元素)和$dino 的关系一样。这些参数必须存放在某个数组变量中, Perl 存放在@_这个变量中。

$n = &max(10,15); #此子程序有2 个参数

sub max{

if($_[0] > $_[1]) {

$_[0];

} else {

$_[1];

}

}

2.6.4 my 变量 默认情况下,Perl 中所有变量都是全局的;

foreach (1..10){

my($square) = $_*$_; #本循环中的私有变量

print "$_ squared is $squrare.\n";

}变量$square 是私有的,仅在此块中可见;在本例中,此块为 foreach 循环块。

my ($num) = @_;         # 列表 context, 同($sum) = @_;

my $num = @_;            # 标量 context, 同$num = @_;任意参数版本:

$maximum = &max(3,5,10,4,6);

//本程序就可以使用任意多个参数

sub max {

my($max_so_far) = shift @_;

foreach (@_){

if($_>$max_so_far){

$max_so_far=$_;

}

}

$max_so_far;  //最后一次计算的默认作为返回值

}

2.7 哈希

2.7.1 什么是哈希 和 Python 的字典一样

2.7.2 哈希元素的存取

$hash {$some_key}作为整体的 hash

要引用整个 hash,使用百分号(“%” )作为前缀。

%some_hash = ("foo",35, "bar", 12.4, 2.5, "hello", "wilma", 1.72e30, "betty", "bye\n");

hash 的值(在列表 context 中)是一个 key/value 对的列表 :

@array_array = %some_hash;

哈希赋值

%new_hash = %old_hash;

%inverse_hash = reverse %any_hash;

大箭头符号 (=>)

my %last_name = (

"fred” => "flintstone",

"dino" => undef,

"barney" => "rubble",

"betty" => "rubble",

);

哈希函数

keys 和 values

my %hash = ("a" => 1, "b" => 2, "c" => 3);

my @k = keys %hash;

my @v = values %hash;

each 函数

while (($key, $value) = each %hash) {

print "$key => $value\n";

}

exists 函数

if (exists $books{$dino}) {

print "Hey, there's a libaray card for dino!\n";

}

delete 函数

my $person = "betty";

delete $books{$person};   # 将$person 的借书卡删除掉

2.8 输入输出

从标准输入设备输入是容易的。使用。在标量 context 中它将返回输入的下一行:

chomp($line=)  由于行输入操作在到达文件的结尾时将返回 undef,这对于从循环退出时非常方便的:

while (defined($line = )) {

print "I saw $line";

}

2.8 哈希

3,程序示例

#!/usr/local/bin/perl -w

@lines = `perldoc -u -f atan2`;

foreach (@lines) {

s//w]+)>//U$1/g;

print;

}

#!/usr/bin/perl

@filename_list=("../tracing023/hadoop-hadoop-jobtracker-tracing023.log","../tracing023/hadoop-hadoop-namenode-tracing023.log","../tracing017/hadoop-hadoop-datanode-tracing017.log","../tracing016/hadoop-hadoop-datanode-tracing016.log","../tracing019/hadoop-hadoop-datanode-tracing019.log","../tracing020/hadoop-hadoop-datanode-tracing020.log","../tracing017/hadoop-hadoop-tasktracker-tracing017.log","../tracing016/hadoop-hadoop-tasktracker-tracing016.log","../tracing019/hadoop-hadoop-tasktracker-tracing019.log","../tracing020/hadoop-hadoop-tasktracker-tracing020.log");

$savefile="./mapAndReduce.result";

&rw($filename,$savefile);

sub rw{

my %map;

my %map_id_time;

#list the ids in jobtracer-tracing017

my %map_ids;

open(IN,$filename_list[0]);

foreach(@lines=)

{

if($_=~/^(.*? .*? ).*Adding task \(REDUCE\) '(attempt_.*?)('| |$|,|\/)/)

{

if(!exists $map_ids{$2})

{

$map_ids{$2}=1;

}

}

}

close IN;

#output the list to file

open(OUT,">ids.result");

foreach(keys %map_ids)

{

print OUT $_."\n";

}

close OUT;

#analyze all the files based on map_ids

foreach(@filename_list)

{

my $filename=$_;

my %tmp_map;

open(IN,$filename);

foreach(@lines=)

{

if($_=~/^(.*? .*? ).*(attempt_.*?)('| |$|,|\/)/ && exists $map_ids{$2})

{

if(!exists $tmp_map{$2})

{

$tmp_map{$2}="\n---------[LOG:".$filename."]---------\n";

}

$tmp_map{$2}.=$_;

if(!exists $map_id_time{$2})

{

$map_id_time{$2}=$1;

}

}

}

foreach(keys %tmp_map)

{

$map{$_}.=$tmp_map{$_};

}

close IN;

}

open(OUT,">".$savefile);

my @list_time_id;

my $index=0;

foreach(keys %map_id_time)

{

$list_time_id[$index][0]=$map_id_time{$_};

$list_time_id[$index][1]=$_;

$index++;

}

my @sort_list_time_id=sort {$a->[0] cmp $b->[0]} @list_time_id;

#@blk_list2=sort {$a cmp $b} @blk_list;

for(my $i=0;$i

{

#print $sort_list_time_id[$i][0]."\n";

my $tmp_id=$sort_list_time_id[$i][1];

print OUT "\n/***********".$tmp_id."**********/\n";

print OUT $map{$tmp_id};

print OUT "\n";

}

close OUT;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值