Perl
1.简介
Practical Extraction and Report Language 实用报表提取语言
#!/usr/bin/perl
print "Hello, World!\n";
2.基础语法
./script.pl
perl script.pl #执行perl脚本文件
perl -e 'print "Hello World\n"' #-e 执行perl代码
print "Hello World\n" #使用\来转义字符,\n为换行
print ("Hello World\n") #可以用双引号或者括号
print "Hello World\n" #不感知空白
print "Hello World\n" #空白在字符串内会原样输出
print 'Hello World\n' #双引号解析转义字符和变量,单引号不会
#注释用#
=pod
这是多行注释
以=开头,后面必须接一个字符 以=cut结尾
=cut
Here文档
$a=10
$var = <<"EOF";
这是一个here文档,要保证结束标志和开始标志一致,EOF可以替换
可以在这里输入字符串和变量,a=$a.
EOF
print "$var\n"
3.数据类型
$digital = 123; #使用$为标量,可以是数字、字符串、浮点数
@array = (1,2,3,4,5); #使用@为数组,索引从0开始
%haxi = ('a'=>1,'b'=>2); #使用%为无序的哈希键值对集合,使用键来获取值
数字字面量
#1.整型 perl把整数存在浮点寄存器中
$x = 123;
if (1+1=2) {执行语句块}
$var1 = 077; #8进制以0开始,077=63
$var2 = 0x1f #16进制以0x开始,0x1f=31
#2.浮点数
浮点数存储不精确,指数范围-309到+308
$float1 = 1.2;
$float2 = -0.3;
$float3 = .3;
$float4 = 3.;
$float5 = 12.3e+04;
$float6 = 5.67e08;
#3.字符串
$var = '字符串';
print($var);
#转义字符
\\反斜线 \'单引号 \"双引号 \a系统响铃 \b退格 \f换页符 \n换行 \r回车 \t水平制表符 \v垂直制表符
\u强制下一个字符为大写 \U强制所有字符为大写 \l强制下一个字符为小写 \L强制所有字符为小写
\Q将到\E为止的非单词字符加上反斜线 \E结束\L \U \Q
4.变量
#创建标量变量
$age = 26;
$name = "dzw";
$salary = 16123.50;
#数组变量
@ages = (25,26,27);
print "$ages[0]\n" #25
print "$ages[1]\n" #26
print "$ages[2]\n" #27
#哈希变量
%data = ('huawei',100,'haisi',10,'kirin',1);
print "$data{'haisi'}\n" #10
#变量上下文
指表达式所在的位置
@names = ('huawei','haisi','kirin');
@copys = @names; #复制一个数组
$size = @names; #赋值给标量
print "@copy\n" #返回数组所有元素 huawei haisi kirin
print "$size\n" #返回数组元素个数 3
#标量运算
$str = "hello" . "world" #连接字符串 helloworld
#特殊字符
print "__FILE__"."\n" #打印文件名test.pl
print "__LINE__"."\n" #打印行号 5
print "__PACKAGE__"."\n" #打印包名main
$vv = v102.111.111;
print "$vv\n" #一个以v开头后面跟一个或多个点的整数,会被认为是一个字串文本 foo
5.数组
@array = (1,2,'hello'); #创建数组
@array = qw/这是一个数组/; #通过qw//创建数组
$array[0] = 'Monday' #通过索引赋值
print '$array[0]\n'; #访问数组元素 Monday
print '$array[-1]\n'; #负数,反向读取 hello
@var10 = (1..10); #..按序列输出 1 2 3 4 5 6 7 8 9 10
print scalar @var10,"\n" #数组大小 10
$var10[50] = 8;
$size = @var10 #返回数组物理大小 51 而不是元素个数
$max_index = $#array; #返回最大索引 50
@huawei = ("haisi","kirin","balong");
$size = @huawei; #返回3
$size = push(@huawei,"xiaolong"); #在数组结尾添加元素 返回4
$size = unshift(@huawei,"tsmc"); #在数组开头添加元素 返回5
@huawei1 = @huawei[1..3]; #切割数组,返回haisi kirin balong
$str = pop(@huawei); #删除最后一个元素,返回删除值xiaolong
$str = shift(@huawei); #删除开头的元素,返回删除值tsmc
@nums = (1..30);
splice(@nums,2,3,10..12); #元素替换 2为起始索引,3为要替换的个数,10..12替换元素列表 返回1 2 10 11 12 6 7 8
#字符串转数组
$var1 = "huawei";
$var2 = "www-huawei-com";
@hua = split('',$var1);
@wei = split('-',$var2);
#数组转为字符串
$str1 = join(',',@hua);
$str2 = join('-',@wei);
#数组排序 根据ASCII数值
@new = sort(@huawei);
#特殊变量$[ 表示第一个索引值 一般为0
$[ = 1; #设置从1开始
@nums = ((1,2,3),(4,5,6)); #合并数组
@list = (1,2,3,4,5,6)[2..4] #选择列表元素,输出3 4 5
6.哈希
%data = ('hua','hongmeng','wei','haisi'); #第一个元素为key 第二个为value
%data = ('hua'=>'hongmeng','wei'=>'haisi'); #也可以用=>
%data = (-hua=>'hongmeng',-wei=>'haisi'); #用-代替引号,这种方式key不能出现空格
$val = $data{-hua}; #访问元素
@array = @data{-hua,-wei}; #读取哈希值
@names = keys %data #读取所有key
@names = values %data #读取所有值
if(exists($data{'facebook'})){
print "$data{'facebook'} \n";
} #判断是否存在元素
@keys = keys %data;
$size = @keys; #获取哈希大小 2
$data{'facebook'} = 'twitter'; #添加哈希元素
delete $data{'facebook'}; #删除哈希元素
#迭代哈希
foreach $key (keys %data){
print "$data{$key}\n";
}
while(($key,$value) = each(%data)){
print "$data{$key}\n";
} #条件为true时重复执行
7.循环
for( $a = 0; $a < 5; $a = $a + 1 ){
print "a 的值为: $a\n";
} #$a = 0只会被执行一次;判断条件a < 5,为true执行循环,false则终止
for( ; ; ){
printf "循环会无限执行\n";
}
8.运算符
算术运算符 + - * / % **
比较运算符 == != > < >= <=
<==>检查是否相等,左边大返回1,左边小返回-1,相等返回0
字符串比较
lt 左边小于右边返回true lower than
gt 左边大于右边返回true
le 左边小于等于右边
ge 左边大于等于右边
eq 等于
ne 不等于
cmp 左边大返回1,左边小返回-1,相等返回0
赋值 = += -= *= /= %= **=
位运算 & | ^ ~ << >>
逻辑运算符 and && or || not
其他运算符
. 连接字符串
x 返回重复字符串,如('-' x 3)输出---
++ 自增运算符
-- 自减运算符
-> 指定一个类的方法
9.时间日期
sec 秒 0-61
min 分钟 0-59
hour 小时 0-24
mday 天 1-31
mon 月 0-11
year 年 从1900开始
wday 星期几 0-6 0表示周日
yday 一年中的第几天 0-364,365
isdst 如果夏令时有效 为真
$now_time = localtime();
print "now_time\n"; #返回系统当前设置的时区时间
$gm_time = gmtime(); #返回格林威治时间,和中国相差8个小时
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); #格式化时间
printf("%02d:%02d:%02d",$hour,$min,$sec);
$old_time = time(); #返回从1970.1.1累计的秒数
$datestring = strftime "%Y-%m-%d %H:%M:%S", localtime; #strftime函数格式化时间
%a星期几简称 %A星期几全称 %b月简称 %B月全称 %c日期和时间 %C年份除以100取证 %d一个月的第几天
%D日期=%m/%d/%y %e一个月的第几天 %F=%Y-%m-%d %g年份后两位数 %h=%b %H24小时制 %I12小时制
10.子程序(函数)
通过sub构造函数,用函数名调用
sub Hello{
print "Hello, World!\n";
}
Hello();
#调用整个数组参数@_ 第一个参数使用$_[0]
sub Average{
$n = scalar(@_);
$sum = 0;
foreach $item (@_){
$sum += $item;
}
$average = $sum / $n;
}
Average(10, 20, 30);
#传入标量和数组参数时,需要把列表放在最后一个参数上
PrintList($a, @b);
#子程序支持return返回值,如果没有则最后一行语句将作为返回值
return $_[0]+$_[1];
#引用
sub return_multiple_data {
my @array1 = (1, 2, 3);
my %hash1 = ('key1' => 'value1', 'key2' => 'value2');
return (\@array1, \%hash1);
}
my ($array_ref1, $hash_ref1) = return_multiple_data();
默认为全局变量,通过my设置私有变量,只在闭合域内有效
使用local为全局变量临时赋值,退出作用域后失效
11.引用
$global = \$foo #前面加\即引用
$global = \@array
$global = \%env
$global = \&hand
$global = \*foo
#根据不同类型取消引用
@var = (1, 2, 3);
$r = \@var; # $r 引用 @var 数组
print "@var 为: ", @$r, "\n"; # 输出本地存储的 $r 的变量值,标量$$r,哈希%$r
#ref查看引用类型 只有SCALAR ARRAY HASH CODE GLOB REF
@var = (1, 2, 3);
$r = \@var;
print ref($r), "\n"; #ARRAY
$cref = \&PrintHash; #创建函数的引用 \&
&$cref(%hash); #使用引用调用函数 &+创建的引用名
12.格式化输出
13.文件操作
14.目录操作
$dir = "/tmp/*.c"; #使用glob显示/tmp目录下所有.c结尾的文件
@files = glob( $dir );
foreach (@files ){
print $_ . "\n";
}
opendir (DIR, '.') or die "无法打开目录, $!";
while ($file = readdir DIR) {
print "$file\n";
}
closedir DIR;
use Cwd;
my $dir = getcwd; #获取当前路径
mkdir( $dir ) or die "无法创建 $dir 目录, $!";
rmdir( $dir ) or die "无法删除 $dir 目录, $!";
chdir( $dir ) or die "无法切换目录到 $dir , $!";
15.错误处理
当打开一个不存在的文件
if(open(DATA, $file)){
...
}else{
die "Error: 无法打开文件 - $!";
}
open(DATA, $file) || die "Error: 无法打开文件 - $!"; #if...else简写
unless(chdir("/etc")){
die "Error: 无法打开目录 - $!";
}
die "Error: 无法打开目录!: $!" unless(chdir("/etc")); #unless与if相反,false才执行,简写
print(exists($hash{value}) ? '存在' : '不存在',"\n"); #三元运算符
chdir('/etc') or warn "无法切换目录"; #warn只会警告
chdir('/etc') or die "无法切换目录"; #die类似warn,且会执行退出
16.特殊变量
$_ 没有给出其他变量时是 "foreach" 循环的默认迭代变量。
17.正则表达式
匹配 m// 简写为// 替换s/// 转化tr///
一般和 =~匹配 !~不匹配 搭配使用
$bar = "run";
if ($bar =~ /run/){
print "匹配\n";
}
模式匹配=~
i忽略大小写 m多行模式 o仅赋值一次 s单行模式 x忽略空白 g全局匹配 cg匹配失败再次匹配
#$` $& $'
$string = "welcome to runoob site.";
$string =~ m/run/;
print "匹配字符串前面部分: $`\n";
print "匹配的字符串: $&\n";
print "匹配字符串后面部分: $'\n";
替换操作符s///
i忽略大小写 m多行 o执行一次 s x忽略空白 g替换所有 e替换字符串作为表达式
$string =~ s/huawei/haisi/;
转化操作符
c转化所有未指定字符 d删除所有指定字符 s删除相同字符
$string = 'runoob';
$string =~ tr/a-z/A-Z/s; #runob
$string =~ tr/\d/ /c; # 把所有非数字字符替换为空格
$string =~ tr/\t //d; # 删除tab和空格
$string =~ tr/0-9/ /cs # 把数字间的其它字符替换为一个空格。
18.发送邮件
$to = '3153284792@qq.com'; #接收邮箱
$from = '445722658@qq.com'; #发送者邮箱
$subject = ''; #标题
$message = ''; #内容