Skip to content

Head First Perl - an introduction

入门例子

#!/usr/bin/env perl
print "Command is: $0\n";
for my $arg ( @ARGV ) {
    print $arg, "\n";
}
exit 0;
  • my是一个声明变量的函数,我们在for循环中,常常需要一个临时变量来存储每次循环获取的变量值,我们通常会在for语句中夹带一个my声明,这样的好处是:使得$arg的作用域仅限于此for循环结构
  • Perl语句是以分号;作为结束标志

变量分类

saclar

标量以$开始,后面紧跟一个字母或者下划线

my $num1 = 10;         # 10
my $num2 = $num1 * 10; # 100
my ($num3, $num4, $num5) = (1, $num2 + 1, 3);
$num1 = $num2 = $num3 = 0
## my既可以每次赋值一个标量,也可以赋值多个标量,还可以连续赋值

my $str1 = 'ABC';       # ABC
my $str2 = '$str1 xyz'; # $str1 xyz
my $str3 = "$str1 xyz"; # ABC xyz
## 双引号内如果含有变量,则此变量的值会被插值(interpolate),即变量名会被其内容替换,单引号内的变量则不会被插值

my $str5 = 'here is \' and \\';  # here is ' and \
## 单引号包围的字符串中,除了两个特殊字符'(单引号)和\(反斜杠),其余字符都会保持它本来的样子

my $str6 = $str1 . "_" . "xyz"; # ABC_xyz
## 字符串拼接,使用.

array

数组的名称,必须以@符号开始,后面紧跟一个字母或者下划线

my @nums = ( 1, 4, 9, 16 );
my @vars1 = ( "AAA", "BBB", "CCC" );
my @vars2 = ( "aaa", "bbb", "ccc" );

$nums[0] = 0;           # now @nums is: (0, 4, 9, 16)
$nums[4] = 17;          # now @nums is: (0, 4, 9, 16, 17)
$vars1[1] = "DDDD";

## $#后面紧跟数组名,表示该数组的最后一个元素的下标
print 'last index of @vars1 is: ',  $#vars1, "\n";
# last index of @vars1 is: 2

## scalar函数,会返回数组的大小,即所含元素的数量
print '@vars2 has ', scalar @vars2, " element\n";
# @vars2 has 3 element

hash

散列名必须以%开头,后面紧跟一个字母或者下划线

%pcc_of = (
  'ZheJiang'    => 'HangZhou',
  'JiangXi'     => 'NanChang',
  'XiZang'      => 'LaSa',
);
print $pcc_of{'JiangXi'}, "\n";

## 使用delete函数进行删除操作
$one_hash{'akey'} = "something";
print $one_hash{'akey'}, "\n";
delete $one_hash{'akey'};
print $one_hash{'akey'}, "\n";

变量组合

%array_of = (
  "keyA" =>  ["a1", "a2", "a3"],
  "keyB" =>  ["b1", "b2"],
);

%hash_of = (
  "keyA" => { "k1" => "valueA1",
              "k2" => "valueA2",
            },
  "keyB" => { "k1" => "valueB1",
              "k2" => "valueB2",
            },
);

循环

for

for my $var ( @someArray ) {
  if ( condition1 ) {
    last;
  }
  ## Other sentences ;
}
  • 如果有嵌套的循环,last;一般只会跳出最内层的循环
  • 如果需要跳出外层的循环,可以使用标记(label
  • 如果想略过循环体的后续的语句,跳到下一次循环,可以使用next;命令
#!/usr/bin/env perl

my ($opt, %value_of_opt);
for my $arg ( @ARGV ) { 
    if ( $arg =~ /^-/ ) {
        $opt = $arg;
    }
    else {
        $value_of_opt{$opt} = $arg;
    }
}

for my $opt ( keys %value_of_opt ) {
    print "$opt => $value_of_opt{$opt}\n";
}
exit 0;

判断

if

if ( condition1 ) {
    # sentences1
} elsif {
    # sentences2
} else {
    # sentences3
}

true & false

  • 未被赋值的,是假;
  • 数字0,字符串‘0’,空字符串’‘,是假;
  • 其余皆为真
my $t1 = 0;   # false
my $t2 = '0'; # false
my $t3 = '' ; # false
my $t4 = ' '; # true

逻辑运算符

!
&&
||
not
and
or

引用 reference

相当于C语言中的指针,使用起来比指针更方便、更安全,

  • 要创建引用,使用反斜杠“\”。
  • 要解析引用,根据引用所指向的数据类型,使用对应的符号
## 创建
$sref = \$str;
$aref = \@ARGV;
$href = \%ENV;

## 解析
$$sref # ($str)  or ${$sref}
@$aref # (@ARGV) or @{$aref}
%$href # (%ENV)  or %{$href}

子例程

  • 子例程就像其他语言中的函数
  • 由关键字sub定义
  • 大括号包围
my $num = 2;
sub times_three {
  $_[0] = $_[0] * 3;
  print "value: $_[0]\n";
}
times_three($num);
print "num is: $num\n";

模块

  • 一个模块一般是一个文件
  • 文件名的后缀经常是.pm(Perl Module)
perl -e "use perl_module"
#!/usr/bin/env perl
use lib "../perl_module";
use My_perl_module_v1;

系统集成

系统命令相关

## 执行操作系统命令
system "ls", "/tmp";
system("ls /tmp");
$re = system("ls /opt");

## 获取系统命令的输出
my $user = `whoami`;

## 获取和设置环境变量
print "\$USER: $ENV{'USER'}\n";
print "\$PATH: $ENV{'PATH'}\n";
$ENV{'some_env'} = some_value;

读取文件

#!/usr/bin/env perl
open my $fh_input, '<', "./open_file.pl" or die "read file failed: $!";
while ( my $line = <$fh_input> ) {
    print $line;
}
close $fh_input or die "close file failed: $!";

exit 0

写入文件

#!/usr/bin/env perl
open my $fh_output, '>', "write_file.txt";
print $fh_output "This is an example\n";
close $fh_output;

exit 0;

读取目录

#!/usr/bin/env perl
opendir my $dh, "." or die "Error: read directory failed.";
my @filedirs = readdir $dh;
closedir $dh or die "Error: close directory failed.";
for my $f ( @filedirs ) {
    print $f, "\n";
}

exit 0

创建目录

mkdir dir_name[, mask]

Further reading

Perl Project