《Perl语言入门》学习笔记

前言

第1章 简介

第2章 标量数据

  • scalar(标量)
  • 标量数据:表示数据的内容,就是值;
  • 标量变量:表示存储标量数据的容器;

数字

前置零的写法只用于表示数字直接量,不能用于字符串和数字间的自动转换。

字符串

养成加上use utf8;的习惯。

单引号内的字符直接量

  • 单引号字符串中,反斜线表示转义的两种情况:反斜线后面跟反斜线或单引号

双引号内的字符直接量

  • 与单引号相比,转义字符的内容更加强大。
组合意义
\n换行
\t水平制表符
\r回车
\f换页符
\b退格
\a系统响铃
\e跳出(ASCII编码的转义字符)
\\反斜线
\“双引号
\l将下个字母转为小写
\L将它后面的所有字符都转为小写,直到\E为止
\u将下个字母转为大写
\U将它后面的所有字符都转为大写,直到\E为止
\E结束\L、\U和\Q开始的作用范围

字符串操作符

操作符可以使用句点符号.进行拼接!

Perl的内置警告信息

  • 形式1:
#!/usr/bin/perl
use warnings;
  • 形式2:
#!/usr/bin/perl -w
  • 形式3:
    运行时加上 -w选项!
  • use diagnostics;报告核心内容

标量变量(variable)

和其他语言一样,只是perl的变量需要拿钱买来,形如$fred

print输出结果

  • say代替print输出结果
perl -E 'say q(hello, world)'                                   [255]
hello, world

字符串中的标量变量内插

变量内插有时候又叫双引号内插

比较操作符

  • 注记:
  • lt:less than
  • gt:greater
  • eq:equal
比较数字字符串
相等==eq
不等!=ne
大于>=lt
小于<gt
小于或等于<=le
大于或等于>=ge

if控制结构

  • 和其他语言一样

获取用户输入

$line = <STDIN>

chomp操作符

  • 取消末尾的换行符
  • chomp函数的返回值是移除的字符数
chomp($text = <STDIN>);#读取不带换行符的输入

#等价于
$text = <STDIN>;
chomp($text);

while控制结构

  • 与其他语言一样

undef值

ubdef作为数字、字符串使用时会被视作数字零空字符串

defined函数

defined函数:判断某个字符串是否为空,如果是undef,返回假!

习题

在这里插入图片描述

第3章 列表与数组

访问数组中的元素

注意$fred[0]fred是两个不同的东西

特殊的数组索引

如果数组定义如下:

$name[0] = 'a';
······
$name[88] = 'asd';

最后一个元素的索引可以是$#name-1

列表直接量

(1, 2, 3) #包含三个数字的列表
(1,"fred", 2) #列表内元素存储格式灵活

(1..100) #从1到100的整数序列

qw简写

  • qw表示为quoted word引号引用的词quoted by whitespace空白引用的词
("fred", "barney", "betty", "wilma", "dino")

# 等价的几种写法,少了很多引号,方便使用!
qw( fred barney betty wilma dino )
qw! fred barney betty wilma dino !
qw{ fred barney betty wilma dino }
qw[ fred barney betty wilma dino ]
qw/ fred barney betty wilma dino /
qw< fred barney betty wilma dino >
qw# fred barney betty wilma dino #
······

列表的赋值

pop和push操作符

  • 删除增加数组末尾元素

shift和unshift操作符

  • 删除增加数组开头元素

splice操作符

splice 最多接收4个参数,分别为目标数组操作数组的开始索引操作的元素个数替换的元素

字符串中的数组内插

  • 注意在使用@符号的时候,在输入邮箱的时候,需要用转义符!

foreach控制结构

  • 和c++中的增强for循环类似。在这里,perl会有默认变量来接收!

Perl最喜欢用的默认变量:$_

reverse操作符

  • 操作后如果需要更数组内容,就需要用数组去接收,否则不会生效!

sort操作符

  • 此处的sort还不能很完美的支持数字的排序,因为仅仅根据ascii顺序排序的!

标量上下文与列表上下文

  • 此处想表达的是,相同的符号在不同的语境下有不同的含义!
  • 比如,数字 + 数组 得到的是 数字数组名与数字进行比较时,数组名返回的是数组的长度

在标量上下文中使用产生列表的表达式

  • 同样是 reverse数组 操作,接收的类型不同,得到的内容就不同!
  • 如果是数组接收,以数组元素为最小单位翻转
  • 如果是标量接收,以最小字符为最小单位翻转

在列表上下文中使用产生标量的表达式

列表上下文中的

  • 如果接收的是数组类型,则可以多行输入;

习题

在这里插入图片描述

第4章 子程序

  • 前文用到内置的系统函数有chompreverseprint
  • 和其他语言类似,perl也可以自己定义子程序,子程序名属于独立的命名空间,调用子程序一般需要加上&

定义子程序

  • 子程序的形式,如下所示:
sub marine {
	$n += 1; # 全局变量$n
	print "Hello, sailor number $n!\n"
}
  • 与c语言相比,perl子程序的定义可以出现在任何位置,也不需要出现函数的声明;
  • 如上的子程序,操作的是全局变量,也就是说,前文用到的都是全局变量

调用子程序

  • 调用子程序,又可以叫呼叫子程序
  • 子程序名前面加上&就可以调用,如调用上面的子程序可以用&marine;
  • 如果学过c/c++,不知道这里是否可以理解为取内存中的地址,然后执行?

返回值

  • 调用子程序都会有返回值
  • 每次写返回值表达式显得费时费力
  • perl的返回值简化为,返回子程序执行过程中最后一次运算的结果
  • 小心检查最后的返回值是不是你想要的内容!你晓得吧!

参数

  • 在调用的传参时候,perl会自动参数劣列表转化为数组变量@_;
  • 如下定义的子程序,可以使用&max(10,15);这样的形式进行传参调用!
sub max {
	if(@_[0] > @_[1]){
		$_[0];
	} else {
		$_[1];
	}
}

子程序中的私有变量

  • 使用my定义私有变量,如下所示
sub max {
	my($m, &n);    # 该语句块中的新私有变量
	($m, &n) = @_; # 将该参数赋值给变量
	if ($m > $n) { $m } else { $n }  # 只有写成一行时,内部的分号才可以省略
}
  • 当然定义和初始化可以放在一行语句内,如下:
sub max {
	my($m, &n) = @_; # 对子程序的参数命名
	if ($m > $n) { $m } else { $n }  # 只有写成一行时,内部的分号才可以省略
}

变长参数列表

  • 可以在子程序内部开头判断传入参数的个数,是否符合预期!
sub max {
	if (@_ != 2) {print "WARNING!应该传入两个参数!"}
	my($m, &n) = @_; # 对子程序的参数命名
	if ($m > $n) { $m } else { $n }  # 只有写成一行时,内部的分号才可以省略
}

改进版的&max子程序

  • 这里其实就是选择比较法,需要理解的就是@_$_;
  • @_:子程序参数列表
  • $_:foreach循环读到的值
#!/usr/bin/perl -w

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

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

空列表参数

  • 需要注意的是,返回值可能为undef

用my声明的词法变量

  • my操作符并不会更改变量赋值时的上下文!
my($num) = @_; # 列表上下文,和($num) = @_;相同
my $num  = @_; # 标量上下文,和 $num  = @_;相同
  • my操作符不加括号时,只能声明靠近的单个词法变量!
  • 推荐使用my操作符定义自己的私有变量

use strict 编译指令

  • 开启这个编译指令,就要求在自定义变量声明前,必须加上my
  • use strict;:强制使用严格、良好的编程风格
  • use v5.12:自动加载strict编译指令
  • 大部分人的建议:比屏幕长的程序都应该加上use strict;

return操作符

  • 满足条件后,终止子程序!

省略与号

  • 在调用子程序时,传入参数时,可以完全省略&:编译器能明显感知到调用的是子程序
  • 自定义子程序,如果命名与内置函数重名,调用时一定要加上&

非标量返回值

  • 返回值可以是标量,也可以是列表!

持久化私有变量

  • 此处引入关键字state,在子程序中,可以一直存在,小编认为是c语言形式的static的修饰,仍然在全局区!

子程序签名

  • 乍一看,这个特性的加入,使其表现形式越来越像c语言函数的写法

习题

在这里插入图片描述
在这里插入图片描述

第5章 输入与输出

读取标准输入

  • 行输入操作符:<STDIN>与Perl的默认变量$_之间并无直接关联!
  • comp:截掉最后的换行符
  • defined:可以用来判断是否读取到末尾!
  • 下面有两个程序,执行效果相同,但他们的原理真的相同吗?
  • while实现的:
while(<STDIN>) {
	print "I saw $_";
}
  • foreach实现的:
foreach(<STDIN>) {
	print "I saw $_";
}
  • 结果就是,不一样:foreach是先把数据全部读进来;而while是读一行执行一行;如果要处理400MB数据,估计还是选择while好一点!

来自钻石操作符的输入

  • 钻石操作符<>的名字竟然是Larry的女儿命名的!
  • 钻石操作符是行输入操作符的特例,通常会处理所有的输入,所以在程序中一般只出现一次!
  • 下面展示两个相同功能的代码!
  • 代码1:
while(<>){
	chomp;
	print "It was $_ that I saw!\n";
}
  • 代码2:
while(defined($line = <>)){
	chomp($line);
	print "It was $_ that I saw!\n";
}

双钻石操作符

  • 如果命令行传入的文件名中包含==管道符|==等特殊字符,就会引发管道等特殊操作。
  • 因此引入<<>>双钻石操作符,功能没变

调用参数

  • 钻石操作符并不会检查命令行参数,其实也只是把命令行参数存放到@ARGV
  • 因此,可以通过修改@ARGV的内容,强制修改钻石操作符要读取的内容
@ARGV = qw{larry moe curly}; #强制让钻石操作符只读取这三个文件
while(<>){
	chomp;
	print "It was $_ that I saw in some stooge-link file!\n"
}

输出到标准输出

  • 下面两种打印输出有什么区别?
  • print @array;
  • print “@array”;
  • 第二行输出的时候,会在元素之间添加空格;
  • 行缓冲,也是是用换行符来进行刷新的!
  • print加括号和不加括号的区别,注意!

用printf格式化输出

  • 这里和c语言的格式高度类似,printf使用后面的括号是选择性的,如果加上,和C语言就一样了!
  • 参数宽度也可以作为参数另外指定!
  • 如下的格式:
#!/usr/bin/perl -w
use strict;
use warnings;
print "Hello world\n";

printf("这里直接是以字符串的格式输出的:\n");
printf "%*s\n", 10, "wilma";
printf("%*s\n", 10, "wilma");

printf("注意,此处参数宽度用参数传入:\n");
printf "%*.*f\n", 6, 2, 3.1415926;
printf("%*.*f\n", 6, 3, 3.1415926);

  • 运行结果如下:
Hello world
这里直接是以字符串的格式输出的:
     wilma
     wilma
注意,此处参数宽度用参数传入:
  3.14
 3.142

数组和printf

  • 有没有发现和python的格式化输出也一样!
  • 再一次感受到,编程思想比编程语言本身重要很多!
my @items = qw{ wilma dino pebbles };

printf "printf输出添加括号:\n";
printf("The items are:\n".("%10s\n" x @items), @items);

printf "printf输出不加括号:\n";
printf "The items are:\n".("%10s\n" x @items), @items;

  • 运行结果:
printf输出添加括号:
The items are:
     wilma
      dino
   pebbles
printf输出不加括号:
The items are:
     wilma
      dino
   pebbles

文件句柄

  • 注意联系I/O操作,6个保留的文件句柄:STDINSTDOUTSTDERRDATAARGVARGVOUT

打开文件句柄

open CONFIG, 'dino';  # 可读可写
open CONFIG, '<dino'; # 只读
open BEDROCK, '>fred';# 可写
open LOG, '>>logfile';# 可追加写
open CONFIG, 'dino';  # 可读可写
open CONFIG, '<', 'dino'; # 只读
open BEDROCK, '>', 'fred';# 可写
open LOG, '>>:encoding(UTF-8)', 'logfile';# 可追加写,还可以指定特定编码

以二进制方式读写文件句柄

  • 句柄前加上binmode,直接以二进制数据流的方式读写。即使在二进制文件中碰巧出现内部编码和换行符相同的字符,也不会将其当做文本文件中的换行符来处理。

异常文件句柄的处理

my $success = open LOG, '>>','logfile'; # 通过返回值可以判断是否成功?
if(!$success){
	# open 操作失败
}

关闭文件句柄

  • 有打开就要有关闭,close,就如C中,有malloc就要有free;C++中,有new就要有delete;

用die处理致命错误

  • die函数的参数是要发出的错误信息文本,一般会输出到标准错误流,同时让程序退出运行
  • 注意下面程序,$!记录的是程序最后返回给操作系统的错误代码!
  • 小编怀疑,die也是由linux中系统函数perror封装的,但只是猜测
if(! open LOG, '>>', 'logfile') {
	die "Cannot create logfile:$!";
}

用warn发出警告信息

  • die相比,warn不会终止程序的运行

自动检测致命错误

  • 在使用的时候,在前面加上use autodie;这种声明,就会自动判断!

使用文件句柄

  • 有点像c中的sprintf
print LOG "Captain's log, stardate 3.145159\n" #输出到文件句柄 LOG
printf STDERR "%d percent complet.\n", $done/$total * 100;

改换用于输出的默认文件句柄

  • print和printf的默认输出句柄是STDOUT,我们可以使用select BEDROCK;格式来进行切换输出句柄

重新打开标准文件句柄

  • 在重新打开了 STDERR之后,任何从Perl产生的错误信息都会送到新的文件里。但如果程序执行到die这部分的代码,那会怎样呢?也就是说,如果无法成功打开文件来接收错误信息,那么错误信息会流到哪里去?
  • 在重新打开这三个系统文件句柄 STDIN、 STDOUT或 STDERR失败时,Perl会热心地帮你找回原先的文件句柄。也就是说,Perl只有在成功打开新的句柄连接时,才会关闭默认的系统文件句柄。

用say来输出

  • 输出内容并换行时,可以使用say函数
  • 这是perl 5.10的新特性,可以多试试

标量变量中的文件句柄

  • 使用裸字和标量变量,根据需要进行选取

习题

在这里插入图片描述

第6章 哈希

什么是哈希?

  • 名字之前有一个美元符号,之后有一个花括号
  • sv中的关联数组

访问哈希元素

  • $hash{$some_key}

访问整个哈希

  • %作为前缀,%hash

胖剪头

  • =>左边是键,右边是值;

哈希操作函数

keys和values

my %hash = ('a' => 1, 'b' => 2, 'c' => 3);
my @k = keys %hash;
my @v = values %hash;

my $count = keys %hash; # 返回键值对的个数

if(%hash) {
	print "hash 不为空"}

each函数

  • 遍历哈希的每个键值对,可以使用each,每次调用都会返回一个键,一个值
while (($key, $value) = each %hash) {
	print "$key => $value\n";
}
  • 一个推荐的函数
foreach $key (sort keys %hash){
	$values = $hash($key);
	print "$key => $value\n";
	# 或者,可以略去额外的 $value 变量
	# print “$key => $hash{$key}\n”;
}

哈希的典型应用

exists函数

  • 检查哈希中是否存在某个键
if (exists $hash{"key"}){
	# 存在
}

delete函数

  • 直接删除指定的键和值。如果没有这样的键,那就结束,也不会出现警告或错误提示;

哈希元素内插

foreach $person (sort keys %books) {
	if ($books{$person}) {
		print "$person has $books{$person} items";
	}
}

特殊哈希%ENV

  • Perl会把环境信息放到特殊哈希%ENV里面

习题

在这里插入图片描述

第7章 正则表达式

  • regular expression

序列

$_ = "yabba dabba doo";
if (/abba/) {
	print "It matched\n";
}
  • 如上所示,两个斜线就是匹配操作符号!

动手实践不同模式

  • 上面的小程序就够了

通配符

  • 点号.能匹配除换行外的任意单个字符

量词

  • 指定匹配项的的重复次数。
  • 最简单的量词是前一个字符出现n次或0次
  • 量词*:前一个字符出现n次或0次,常用于匹配不固定长度的空白字符
  • .*:贪婪匹配,可以匹配任意非换行字符任意次

模式分组

  • 用圆括号( )将模式字符串分组
  • (.)\1:匹配连续出现的两个同样字符

择一匹配

  • |:或的关系

字符集

[a=z] # a到z的全部小写字母
[-a]  # 连字符 或者 a
[^n-z] #不是n到z的字符

简写的反义形式

[a]的相反形式可以是[^a]

简写匹配
\d十进制数字
\D非十进制数字
\s空白字符
\S非空白字符
\h水平空白字符(Perl 5.10起支持)
\H非水平空白字符(Perl 5.10起支持)
\v纵向空白字符(Perl 5.10起支持)
\V非纵向空白字符(Perl 5.10起支持)
\R一般化的行结尾符号(Perl 5.10起支持)
\w单词字符
\W非单词字符
\n换行符(不是真正的简写)
\N非换行符(Perl 5.18 起属于稳定特性)

Unicode字符属性

锚位

  • \A:匹配字符串的绝对开头
  • \z:匹配字符串的绝对末尾
  • \b:单词锚位,匹配单词边界

习题

在这里插入图片描述
在这里插入图片描述

第8章 用正则表达式进行匹配

用m//进行匹配

  • 模式匹配操作符:m( )m< >m{ }m[],其中选择斜线作为定界符时,一般省略前面的m,变成了/ /

模式匹配修饰符

/i进行大小写无关的匹配

/s匹配任意字符

  • /.*/s:可以匹配到换行符
  • 如果不习惯用/s修饰符,可以使用[\D\d],[\S\s]等,原理就是数字字符以及非数字字符组合就是任意字符。

/x加入辅助空白字符

  • 使用这个之后,可以在模式里使用空格或换行使得代码可读性更高!

联合使用修饰符

  • 单词匹配多想修饰符
if (/barney.*fred/is){# 同时使用 /i 和 /s
	# 匹配成功
}
  • 用花括号作为定界符,用vim就可以自动定位跳转
if (m{
	barney
	.*
	fred
}isx){     # 或同时使用 /i 、 /s 和 /x
	# 匹配成功
}

选择字符的解释方式

  • Perl 5.14 开始增加了一些用于告诉Perl如何解释字符意义的修饰符,主要是:对大小写的处理以及对字符集合的阐释。

行首和行尾锚位

  • ^\A一样,$\z一样
  • 如果加上/m修饰符,/^/m就会匹配字符串开头和换行符之后的内容(就是每行开头)

绑定操作符=~

  • 正则表达式默认匹配的目标文本是$_,我们可以使用绑定操作操作符=~指定要匹配的目标文本。

捕获变量

  • 捕获变量,把匹配到的内容用标量存储起来,方便调用!一般使用圆括号()进行捕获

捕获变量的存续期

  • 捕获变量的内容一般会保持到下次成功匹配为止,我们可以将其保存下来的;

禁用捕获的括号

  • 在左括号后加上?:,此时的括号仅用于分组,不再捕获匹配字符串。

命名捕获

  • 使用如下的捕获标签,可以随意移动位置,并加入更多的捕获括号!
use v5.10;

my $names = 'Fred or Barney';
if ($names =~ m/(?<name1>\w+) (?:and|or)(?<name2>\w+)){
	say "I saw $+{name1} and $+(name2)";
}

自动捕获变量

  • $`:匹配保存之前的内容
  • $&:匹配保存 的内容
  • $’:匹配保存之后的内容
  • 修饰符/p可以对当前的表达式开启类似的自动捕获变量,变成了${^PREMATCH},${^MATCH},${^POSTMARTCH}

优先级

正则表达式优先级表

正则表达式特性示例
元括号(分组或捕获)(···),(?:···),(?
量词a*,a+,a?,a{n,m}
锚位和字符序列abc, ^, $, \A, \b,\z,\Z
择一a|b|c
原子a,[abc],\d,\l,\g{2}

模式测试程序

#!/usr/bin/perl
while (<>) {                   # take one input line at a time
    chomp;
    if (/YOUR_PATTERN_GOES_HERE/) {
        print "Matched: |$`<$&>$'|\n";  # the special match vars
    } else {
        print "No match: |$_|\n";
    }
}

习题

在这里插入图片描述在这里插入图片描述

第9章 用正则表达式处理文本

s///进行替换操作

s/st1/st2; #试图将st1替换为st2

/g进行全局替换

s/\s+/ /g;  # 将任意连续的空白转换成单一空格
s/\A\s+//g; # 将开头的空白字符替换成空字符串
s/\s+\z//g; # 将结尾的空白字符替换成空字符串
s/\A\s+|\s+\z//g; #去除开头和结尾的空白字符

不同的定界符

  • m//qw//一样,可以改变s///的定界符

替换操作的修饰符

  • 除了/g修饰符外,我们还可以把用在普通模式匹配中的/i/x/s修饰符用在替换操作中

绑定操作符

  • =~s///指定不同的替换目标

非破坏性替换

  • 如果需要同时保留原始字符串和替换后的字符串,该怎么办?
  • 复制拷贝一份再替换
my $original = 'Fred ate 1 rib';
my $copy = $original;
$copy =~ s/\d+ ribs?/10 ribs/;
  • 等价于
(my $copy =  $original )=~ s/\d+ ribs?/10 ribs/;
  • perl 5.14增加了一个/r字符串,就会保留原来字符串中的值不变,把替换结果作为替换操作的返回值返回
use v5.14;
my $copy =  $original =~ s/\d+ ribs?/10 ribs/r;

大小写转换

  • \U将它后面的所有字符转成大写的
  • \L将它后面的所有字符转成小写的
  • 默认情况下,它们会影响之后全部的(替换)字符串,可以用\E关闭大小写转换的功能;
  • 使用小写\l\u,它们只会影响紧随其后的第一个字符;
  • 同时使用\u\L来表示"后续字符全部转为小写的,但首字母大写”

元字符转义

s/\(\(\(Fred/fred/

# 使用\Q简化形式
s/\Q(((Fred/fred/
\

split操作符

  • 格式如下:
my @fields = split /separator/, $string;
  • 例子如下:
  • 注意第二行和第三行
my @fields = split /:/,"abc:def:g:h";    # 得到("abc","def","g","h")
my @fields = split /:/,":::a:b:c:::"     # 得到("","","","a","b","c")
my @fields = split /:/,":::a:b:c:::",-1  # 得到("","","","a","b","c","","","")
  • 默认split会以空白字符分割$_中的字符串;
my @fields = split; # 基本等效于split /\s+/, $_;

join函数

  • join会把胶水涂进每个片段之间并返回结果字符串
my $x = join ":",4,6,8,10,12; # $x 为 “4:6:8:10:12”
my @values = split /:/,$x;    # @values 为(4,6,8,10,12)
my $z = join "-", @values;    # $z为 “4-6-8-10-12”

列表上下文中的m///

更强大的正则表达式

习题

在这里插入图片描述
在这里插入图片描述

第10章 其他控制结构

unless控制结构

  • if条件为真时执行,unless条件为假时执行

伴随unless的else语句

  • 就是if else改成了unless else

until控制结构

  • 颠倒while的条件表达式,就用until

表达式修饰符

  • 简化代码书写
  • 即使条件表达式写在后面,它也会先执行
  • 倒装句
print "$n is a negative number.\n" if $n < 0;
if($n < 0) {
	print "$n is a negative number.\n";
}

裸块控制结构

  • { }主要是为变量限制作用域,和c++一样

elsif子句

  • 注意不是elseif

自增与自减

  • 前置后置,自增自减。

for控制结构

  • 和c语言写法一致

for和foreach之间的秘密

  • for和foreach实际上是等价的。括号中有两个分号,就把它当做for,若没有分号,就把他当做foreach

循环控制

last操作符

  • 和c语言的break一样,退出循环

next操作符

  • 和c语言的continue一样,跳过本次循环

redo操作符

  • 这不是goto语句封装好的吗?

带标签的块

  • 这不就是verilog中的程序块别名吗?

条件操作符

  • 三目运算符? :
  • expression ? if_true_expr : if_false_expr

逻辑操作符

  • 全套的逻辑操作符

短路操作符的返回值

  • 短路操作符可以改为三目运算符

使用部分求值操作符的控制结构

  • &&||//?:都是根据左边的值确定要不要执行右边的表达式

习题

在这里插入图片描述
在这里插入图片描述

第11章 Perl模块

  • 如何使用现有的模块,目的是熟悉使用CPAN完成自己的任务!

寻找模块

安装模块

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用简易模块

习题

在这里插入图片描述

第12章 文件测试

文件测试操作符

stat和lstat函数

loacltime函数

位运算操作符

习题

在这里插入图片描述
在这里插入图片描述

第13章 目录操作

当前工作目录

  • 借助标准模块之一Cwd模块,查看当前的工作目录是哪个
use v5.10;
use Cwd;
say "The current working directory is ",getcwd();
  • 可以使用标准模块之一File::Spec实现相对路径和绝对路径之间的相互转换\

修改工作目录

  • chdir:和shell中的cd一个意思
chdir '/etc' or die "cannot chdir to /etc :$!";
  • 可以使用File::HomeDir模块去往特定用户的主目录,他支持大部分操作系统。

文件名通配

  • 文件名通配:glob
my @all_file = glob '*';
my @pm_file = glob '*.pm';
  • Perl内置的glob并非唯一选择,我们可以用File::Glob模块提供各式兼容和扩展的文件名通配。

文件名通配的隐式语法

my @all_files = <*>; # 效果和这样的写法完全一致: my  @all_files = glob "*";
  • Perl 会把尖括号内出现的变量替换成它的值,类似于双引号内字符串的变量内插,如下
my $dir = '/etc';
my @dir_file = <$dir/* $dir/.*>;

目录句柄

  • 一个例子
my $dir_to_process = '/etc';
opendir my $dh, $dir_to_process or die "Cannot open $dir_to_process:$!";
foreach $file (readdir $dh) {
	print "one file in $dir_to_process is $file\n";
}
closedir $dh;
  • 使用裸字DIR
my $dir_to_process = '/etc';
opendir DIR, $dir_to_process or die "Cannot open $dir_to_process:$!";
foreach $file (readdir DIR) {
	print "one file in $dir_to_process is $file\n";
}
closedir DIR;

文件和目录的操作

删除文件

  • unlink:
unlink 'slate', 'bedrock','lava';
unlink qw{slate bedrock lava};

unlink glob '*.o';
  • unlink返回的是成功删除的文件数目,我们可以把他们放到循环依次删除并检查
foreach my $file (qw(slate bedrock lava)) {
	unlink $file or warn "failed on $file:$!\n";
} 

重命名文件

  • rename 'old','new';
  • 借用胖剪头=>:
  • 如何批量把名称是.old结尾的文件改名为以.new结尾?
foreach my $file (glob "*.old") {
	my $newfile = $file;
	$newfile =~ s/\.old$/.new/;
	if (-e $newfile) {
		warn "can't rename $file to $newfile: $newfile exists\n"
	} elsif(rename $file => $newfile) {
		# 改名成功,什么都不需要做
	} else {
		warn "rename $file to $newfile failed:$!\n";
	}
}
  • 循环里的前两行还可以修改为
my ($newfile = $file) =~ s/\.old$/.new/;
  • 也可以在Perl 5.14里面加上/r修饰符,
use v5.14;
my $newfile = $file =~ s/\.old$/.new/r;

链接与文件

  • 与Linux操作系统的文件作对比吧,inode节点等,确定是软链接这个说法吗?(之前有老师强调过,没有软链接这一说,是符号链接和硬链接)

创建和删除目录

  • 创建失败返回设定值
mkdir 'fred', 0755 or warn "Cannot make fred directory: $!";
  • 移除空目录
foreach my $dir(qw{fred barney betty}) {
	rmdir $dir or warn "cannot rmdir $dir:$!\n";
}
  • 如果要创建临时目录或文件,可以用File::Temp模块

修改权限

  • chmod不支持linux中a+x这种格式,除非从CPAN安装了File::chmod.
  • 常规格式如下:
chmod 0755, 'fred','barney';

修改文件属主

chown $user, $group, glob '*.o';

修改时间戳

my $now = time;
my $ago = $now - 24 * 60 * 60; # 一天的秒数
utime $now, $ago, glob '*';    # 将最后访问时间改为当前时间,最后修改时间改为一天前

习题

在这里插入图片描述
在这里插入图片描述

第14章 字符串与排序

用index查找子字符串

my $where = index($stuff, "wor");

用substr操作子字符串

my $part = substr($string,$initial_position, $length);

用sprintf格式化字符串

my $money = sprintf "%.2f", 2.4997;

高级排序

  • 飞碟操作符’<=>’
my @descending = sort {$b <=> $a} @some_numbers;

按哈希值排序

my %score = ("barney" => 195, "fred" => 205, "dino" => 30);
my @winners = by_score keys %score;

按多个键排序

  • 例子1:
my %score = (
			"barney" => 195, "fred" => 205, 
			"dino" => 30, "bamm-bamm" => 195,
			);
my @winners = by_score_and_name keys %score;

sub by_score_and_name {
	$score{$b} <=> $score{$a} #先按照分数降序排列
	or
	$a cmp $b #分数相同的再按名字的ASCII码序排列
} @winners
  • 例子2:
@patron_IDs = sort{
	&fines($b) <=> &fines($a) or
	$items($b) <=> $items($a) or
	$family_name{$a} cmp $family_name{$b} or
	$personal_name{$a} cmp $family_name{$b} or
	$a <=> $b;
} @patron_IDs;

习题

在这里插入图片描述

第15章 进程管理

习题

在这里插入图片描述
在这里插入图片描述

第16章 高级Perl技巧

习题

在这里插入图片描述

后记

  • 本文内容只是记录了小编想学习的部分,其他部分暂时忽略。
  • 要是工作中需要的话,再深究!
  • 7
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Perl语言入门第七版》是一本介绍Perl编程语言入门教程。Perl是一种通用脚本语言,可用于文本处理、系统管理和网络编程等多个领域。 本书首先介绍了Perl语言的基本概念和语法规则,包括变量、数据类型、运算符、控制结构等。读者可以通过实例代码和练习来巩固对这些知识的理解和掌握。 接下来,本书详细介绍了Perl的字符串处理、正则表达式和文件操作等常用特性。Perl在文本处理方面有着强大的功能,例如字符串的拼接、分割、替换和匹配等,能够帮助开发人员高效地处理文本数据。 此外,本书还介绍了Perl模块的使用方法和编程技巧。Perl模块是一些预定义的函数和变量集合,可以提供额外的功能和功能扩展。通过学习模块的使用,读者能够加深对Perl语言的理解,并能够更加高效地编写程序。 最后,本书还通过实例和项目演练,向读者展示了如何将Perl应用于实际开发中。这些实例涵盖了文件处理、网络编程、系统管理和Web开发等多个领域,帮助读者将所学知识转化为实际应用能力。 总之,《Perl语言入门第七版》是一本全面介绍Perl语言入门教材。通过学习本书,读者可以系统地了解Perl的基本概念和语法规则,掌握Perl在文本处理和系统编程方面的强大功能,并能够将所学知识应用于实际开发中。无论是初学者还是有一定编程经验的开发人员,都可以通过本书打下坚实的Perl编程基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰之行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值