天天看点

Perl学习笔记-1

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;
}      
  1. 数值

    perl中没有整数,统一处理为双精度型数。

    支持多种进制数。

    八进制数 0377

    十六进制数 0xff

    二进制数 0b11111111

    以上都为十进制数255

运算符:+,-,*,**,/,%

  1. 字符串

    perl中如果要使用中文,需

use utf8;      

单引号字符串直接量:\n按照普通字符解释。

双引号字符串直接量:解答转义字符和多进制数。

几个常用转义字符

转义字符 含义
\l 将下一个字母转为小写
\L 将后边的所有字符转为小写,直到\E为止
\u 将下一个字母转换为大写
\U 将后边的所有字符转为大写,直到\E为止
\Q 将后边直到\E的 none word 字符加上反斜线转义
\E 结束操作符

双引号字符串可以完成变量字符内插。

字符串运算符

运算符 含义
. 句点 字符串连接
x 字符串重复。右边的数字是重复的次数

Perl会根据需要自动完成数字和字符串的转换。

  1. 内置警告
在代码前部使用
use warnings;
或者在命令行带-w参数
$ perl -w program
或者在shebang行
#!/bin/perl -w
输出详细告警信息
use diagnostics;
或者在命令行
$ perl -Mdiagnostics ./program      
  1. 变量
  • 以$开头
  • 变量名区分大小写
  • 下划线字母开头
  • 变量名习惯全小写,下划线分割
  • 双引号中可以对$变量完成内插
  1. 双目运算符

    +=

    -=

    .=

  2. 输出特殊字符

    chr() ascii数字转字符

    ord() 字符转ascii数字

    或者

"\x{03b1}\x{03c9}"      
  1. 比较运算符(与shell script相反)
  • 数值比较

    <,<=,==,>,>=,!=

  • 字符串比较

    lt,le,eq,ge,gt,ne

  1. 获取用户输入
$line=<STDIN>
一般会使用chomp()去掉末尾的换行符
chomp($line=<STDIN>)      

注:函数可以加上括号也可以不加。只要不改变表达式的含义()是可以省略的。

  1. 数组
$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. 列表直接量
(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)      
  1. foreach控制结构
foreach $rock (qw/ bedrock slate lava /){
    print "One rock is $rock.\n"
}      

控制变量$rock不是列表元素的复制品,它就是列表元素本身。

  1. 默认变量$_
foreach (1..10){
    #默认使用$_作为控制变量
    print "I can count to $_!\n";
}      

当没有告知perl使用哪个变量或数值时,perl会自动使用$_。

  1. reverse操作符
@fred=6..10;
@barney=reverse(@fred);
@wilma=reverse 6..10;
@fred=reverse @fred;      
  1. sort操作符

    队列表排序。

  2. 使用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";
}      
  1. 子程序
定义
sub{
    ....
    #最后一个表达式的运算结果作为返回值
}
调用
&marine;      

子程序使用@_数组(私有化的,原值被压栈保存)接收参数列表。可以使用如下形式引用参数:

$_[0]        $_[1]      ......     
第一个参数   第二个参数    ......      

使用my定义私有变量

my($m,$n);
my不带括号只能定义一个变量。      

检查参数长度

sub{
    if(@_!=2){
        ...
    }
}      

一个求输入参数中的最大值的子程序例子

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

sub{
    my($max_so_far)=shift @_;
    foreach(@_){
        if($_>$max_so_far){
            $max_so_far=$_;
        }
    }
    $max_so_far;
}      

return 控制子程序中途停止并返回某个值。

使用state操作符来声明变量,可以在子程序的多次调用期间保留变量的值,并将变量的作用域局限于子程序的内部。

  1. 输入输出
  • 钻石操作符

    <> 如果给了命令行参数,就从命令行参数为文件名的文件中读取;如果没有给出命令行参数就从STDIN中读取。钻石操作符可以接收 | 过来的内容。

while(<>){  #将输入读入默认变量$_
    chomp;  #操作默认变量$_
    print "It was $_ that I saw!\n";
}      

命令行参数存放于@ARGV中。钻石操作符会查看@ARGV,然后决定用哪些文件名。如果找到的是空列表,就会改用标准输入流;否则就会使用@ARGV里的文件列表。

  1. 文件句柄
  • 保留文件句柄
保留文件句柄 说明
STDIN 标准输入
STDOUT 标准输出
STDERR 标准出错
DATA
ARGV
ARGVOUT
  • 打开文件句柄
open CONFIG, 'dino';  只读打开
open CONFIG, '<dino'; 只读打开
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;      
  • 用die处理致命错误

    输出指定信息到STDERR,让程序立即终止并返回不为0的退出码。

if(! open LOG, '>>', 'logfile'){
    die "Cannot create logfile: $!";
}      

默认变量“ $ ! ”存储系统错误信息。只有在系统服务请求失败后的瞬间,$!的值才会有用。

if(@ARGV<2){  #标量上下文的行为
    die "Not enough arguments\n";  #\n不让perl带上行号
}      
  • 自动检测致命错误

    编译指令autodie会自动检查致命错误并调用die。

    注意:程序名保存在特殊变量$0中

use autodie;      
  • 使用文件句柄
if(! open PASSWD, "/etc/passwd"){
    die "How did you get logged in? ($!)";
}
while(<PASSWD>){
    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";      
  1. 哈希

    哈希就是键值对。键不能重复,但值可以重复。

$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}      
  1. 常用引号标识
引号标识 含义
q 是单引号
qq 是双引号
qw 单词列表引号
qr 正则表达式引号
qx