CPAN网站 https://metacpan.org/
perl脚本语言时大小写敏感的。
perl脚本的shebang[ʃɪˈbæŋ]行
which perl
#!/bin/perl
#!/usr/bin/perl
分号的作用是分隔不同的perl语句,而不是断行。
第一个样例
#!/usr/bin/perl
@lines=`perldoc -u -fatan2`;
foreach(@lines){
s/\w<[^>]+>/\U$1/g;
print;
}
运算符:+,-,*,**,/,%
use utf8;
单引号字符串直接量:\n按照普通字符解释。
双引号字符串直接量:解答转义字符和多进制数。
几个常用转义字符
转义字符 | 含义 |
---|---|
\l | 将下一个字母转为小写 |
\L | 将后边的所有字符转为小写,直到\E为止 |
\u | 将下一个字母转换为大写 |
\U | 将后边的所有字符转为大写,直到\E为止 |
\Q | 将后边直到\E的 none word 字符加上反斜线转义 |
\E | 结束操作符 |
双引号字符串可以完成变量字符内插。
字符串运算符
运算符 | 含义 |
---|---|
. 句点 | 字符串连接 |
x | 字符串重复。右边的数字是重复的次数 |
Perl会根据需要自动完成数字和字符串的转换。
在代码前部使用
use warnings;
或者在命令行带-w参数
$ perl -w program
或者在shebang行
#!/bin/perl -w
输出详细告警信息
use diagnostics;
或者在命令行
$ perl -Mdiagnostics ./program
双目运算符
+=
-=
.=
输出特殊字符
chr() ascii数字转字符
ord() 字符转ascii数字
或者
"\x{03b1}\x{03c9}"
$line=
一般会使用chomp()去掉末尾的换行符
chomp($line= )
注:函数可以加上括号也可以不加。只要不改变表达式的含义()是可以省略的。
$rocks[0]='bedroom';
最后一个元素的索引值是$#rocks。
使用@(all)来引用整个数组,即数组的所有元素。
@rocks=qw/babe dfef sefe/;
@i=1..10;
@array=5..9;
$fred=pop(@array); 删除最后一个元素
push @array, 8;
push @array, 1..10;
删除开头元素
$n=shift @array;
删除序号2及之后的元素(下标从0开始)
@removed=splice @array, 2;
从1开始删除2个元素
@removed=splice @array, 1, 2;
在指定位置插入元素
splice @array, 1, 0, qw(wilma)
(1, 2, 3)
(1, 2, 3,)
("fred", 4.5)
()
(1..100)
quoted word
qw(fred barney betty wilma dino)
或
qw(
fred
barney
betty
wilma
dino)
()可以是其他字符,只要配对就可以。主要是为了区分。
列表赋值
($fred, $barney, $dino) = ("flinsfga", "fwerc", undef);
交换两个变量的值
($fred, $barney) = ($barney, $fred)
对列表进行赋值时,左边多出的变量会被忽略。
foreach $rock (qw/ bedrock slate lava /){
print "One rock is $rock.\n"
}
控制变量$rock不是列表元素的复制品,它就是列表元素本身。
foreach (1..10){
#默认使用$_作为控制变量
print "I can count to $_!\n";
}
当没有告知perl使用哪个变量或数值时,perl会自动使用$_。
@fred=6..10;
@barney=reverse(@fred);
@wilma=reverse 6..10;
@fred=reverse @fred;
sort操作符
队列表排序。
使用each提取哈希键值对
@rocks=qw/ bedrock slate rubble granite /;
foreach $index (0..$#rocks){
print "$index: $rocks[$index]\n";
}
或者
my @rocks=qw/ bedrock slate rubble granite /;
while(my($index,$value)=each @rocks){
say "$index: $value";
}
定义
sub marine{
....
#最后一个表达式的运算结果作为返回值
}
调用
&marine;
子程序使用@_数组(私有化的,原值被压栈保存)接收参数列表。可以使用如下形式引用参数:
$_[0] $_[1] ......
第一个参数 第二个参数 ......
使用my定义私有变量
my($m,$n);
my不带括号只能定义一个变量。
检查参数长度
sub max{
if(@_!=2){
...
}
}
一个求输入参数中的最大值的子程序例子
$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;
}
return 控制子程序中途停止并返回某个值。
使用state操作符来声明变量,可以在子程序的多次调用期间保留变量的值,并将变量的作用域局限于子程序的内部。
while(<>){ #将输入读入默认变量$_
chomp; #操作默认变量$_
print "It was $_ that I saw!\n";
}
命令行参数存放于@ARGV中。钻石操作符会查看@ARGV,然后决定用哪些文件名。如果找到的是空列表,就会改用标准输入流;否则就会使用@ARGV里的文件列表。
保留文件句柄 | 说明 |
---|---|
STDIN | 标准输入 |
STDOUT | 标准输出 |
STDERR | 标准出错 |
DATA | |
ARGV | |
ARGVOUT |
open CONFIG, 'dino'; 只读打开
open CONFIG, '; 只读打开
open BEDROCK, '>gred'; 覆盖写打开(无则新建)
open LOG, '>>logfile'; 追加写打开(无则新建)
open CONFIG, '<', 'dino';
open BEDROCK, '>', $file_name;
open LOG, '>>', $logfile;
open LOG, '>>', &logfile_name();
open CONFIG, '<:encoding(UTF-8)', 'dino';
open BEDROCK, '>:encoding(UTF-8)', $file_name;
open BEDROCK, '<:crlf', $file_name; 读取DOS回车换行结尾的文件(读入文件的同时把DOS的CR-LF转换为Unix风格的换行符)
open BEDROCK, '>:crlf', $file_name; 写入DOS回车换行结尾的文件
my $selected_output='my_output';
open LOG, "> $selected_output"; 注意>后的空格可以防止覆盖写
可以把所有输入和输出句柄都改为UTF-8编码
use open IN => ':encoding(UTF-8)';
use open OUT => ':encoding(UTF-8)';
或者
use open ':encoding(UTF-8)';
close BEDROCK;
if(! open LOG, '>>', 'logfile'){
die "Cannot create logfile: $!";
}
默认变量“ $ ! ”存储系统错误信息。只有在系统服务请求失败后的瞬间,$!的值才会有用。
if(@ARGV<2){ #标量上下文的行为
die "Not enough arguments\n"; #\n不让perl带上行号
}
use autodie;
if(! open PASSWD, "/etc/passwd"){
die "How did you get logged in? ($!)";
}
while( ){
chomp;
...
}
输出
print LOG "......\n"; #输出到文件句柄
printf STDERR "%d percent complete.\n", $done/$total *100;
使用select改变默认的文件输出句柄
select BEDROCK;
print "...\n";
select LOG;
$|=1; #不要将LOG的内容保留在缓冲区
select STDOUT;
print LOG "...\n";
将错误信息保存
if(! open STDERR,'>>',"/home/bee/.error.log"){
die "Can't open error log for appand: $!";
}
注,使用say将自动加上换行符。
say "Hello!";
say BEDROCK "Hello!"; #支持文件句柄
文件句柄可以使用变量或者裸字。注意perl大小写敏感。
裸字:STDOUT,LOG,MYFILE
变量:$file
例子
open my $rock_fh, '<', 'rocks.txt' or die "Could not open rocks.txt: $!";
while(<$rock_fh>){
chomp;
...
}
print $rock_fh "limestone\n"; #不要加逗号分割
close $rock_fh;
输出到句柄
print STDOUT; #将默认变量$_的内容输出
print { $rock_fh }; #通过{}说明后边接的是文件句柄,且输出$_中的内容。
print { $rocks[0] } "sandstone\n";
$family_name{'fred'}='flintstone';
$family_name{$person}='babala';
使用%来指带整个哈希。哈希与列表可以相互转换。
%some_hash=('foo',35,'bar',12.4,'wilam',23.4);
@any_array=%some_hash;
my %new_hash=%old_hash;
键值对的存储是无序的。
将”键-值“对变为”值-键“对。
my %inverse_hash=reverse %any_hash;
%ip_address= reverse %host_name;
在列表中使用=>
my %last_name=(
'fred' => 'flinestone',
'dino' => undef,
'arnet' => 'rubble',
'betty' => 'ruble'
)
注:左边键的引号可省。
my %last_name=(
fred => 'flinestone',
dino => undef,
arnet => 'rubble',
betty => 'ruble'
)
如果键名是由字母,数字,下划线组成的,并且不以数字开头,就可以省略引号。这种字符序列称为裸字(bareword)。
单个引用哈希时也可以使用裸字。
$score{'fred'}
可写为
$score{fred}
哈希函数
keys函数能返回哈希的键列表。values函数能返回对应的值列表。
my %hash=('a'=>1, 'b'=>2, 'c'=>3);
my @k=keys %hash;
my @v=values %hash;
哈希的判断上下文。
if(%hash){ #只要哈希中有一个键值对,就返回真
print "That was a true value!\n";
}
哈希的遍历
while(($key,$value)=each %hash){
print "$key => $value\n";
}
foreach $key (sort keys %hash){
print "$key => $hash{$key}\n";
...
}
哈希处理函数
函数名 | 含义 |
---|---|
exists | 是否存在某个键 |
delete | 删除对应的键值对 |
读取环境变量的哈希%ENV
$ENV{PATH}
引号标识 | 含义 |
---|---|
q | 是单引号 |
是双引号 | |
qw | 单词列表引号 |
qr | 正则表达式引号 |
qx | 反引号 |