Perl笔记:Perl语言入门(第六版) - IO文件目录

输入与输出

读取标准输入

chomp($line = <STDIN>); #chomp截掉最后的换行符,STDIN标准输入。

while (defined($line = <STDIN>)) {

print "$line";

}

类似

foreach (<STDIN>) {

print "$_";

}

foreach会读取全部输入(所有文件的所有内容),并在列表上下文中处理。while每次循环读取一行,循环至结束。效率可能相差很大。

钻石操作符

另一种读取输入的方法,从标准输入或命令行文件读取。

while (<>) {

chomp;

print "It was $_ that I saw!\n";

}

调用参数

@ARGV放置Perl运行时的命令行参数。可以使用shift等操作符或foreach遍历。

钻石操作符会查看@ARGV,然后决定该用那些文件。

print 输出到标准输出

print @array; #把数组元素打印出来,元素之间不会有空格:123456。

print "@array"; #打印出一个字符串,数组元素内插,元素之间使用空格分隔:1 2 3 4 5 6。

如果数组字符串包含空格可直接输出print @array;不包含可补充print "@array\n";

print  <>;钻石操作符在列表上下文会返回输入行组成的列表,print处理待打印的字符串列表。

除非这样做会改变表达式的意义,否则Perl里的括号可以省略。

假如print的调用看起来像函数调用,它就是函数调用。

print (2+3)*4; <==> (print(2+3)) * 4,输出5,print返回1并和4相乘,然后丢弃结果。

printf格式化输出

%g按恰当的数字形式输出

数组和printf printf "The items are:\n" . ("%10s\n" x @items), @items;

文件句柄

打开文件句柄

文件句柄常用全大写字母命名,以便区分。

6个特殊的保留句柄:STDIN、STDOUT、STDERR、DATA、ARGV、ARGVOUT

open CONFIG, 'dino'; #打开名为CONFIG的文件句柄,指向文件dino;

open CONFIG, '<dino'; #<声明为只读,>创建新文件,如果存在就清除,>>追加。

5.6版后,可用新写法:open CONFIG, '<', 'dino';三个参数。

可指定编码方式open CONFIG, '<:encoding(UTF-8)', 'dino';

简写open BEDROCK, '>:utf8', $file_name; #简写不检查编码方式是否正确,全些会确认编码方式的正确性。

打印Perl能理解和处理的字符编码清单:perl -MEncode -le "print for Encode->encodings(':all')"

以二进制方式读写文件句柄:binmode STDIN, ':encoding(UTF-8)';

open返回布尔值表示执行是否成功

关闭文件句柄

close BEDROCK;

重新打开句柄时,Perl会自动关闭原先的句柄

输出错误

用die处理致命错误

die函数输出指定信息到标准错误,并立即终止程序返回不为零的退出码。

die "Cannot create logfile: $!";

$!可读的系统错误信息。只有系统服务请求失败后,$!才会有用

die会自动将Perl的程序名和行号附加到错误信息后面。

warn 送出警告信息

功能类似于die,但不终止程序。

自动检测致命错误

use autodie;

使用文件句柄

文件句柄以读取模式打开后,可以使用像STDIN的方法读取数据

<FILE_HANDLE> 行输入操作符,由尖括号和文件句柄组成。

以写入或添加模式打开的文件,可以使用print或printf

printf STDERR "%d precent complete.\n", $done/$total*100; #句柄后无逗号

printf (STDERR "%d precent complete.\n", $done/$total*100); #正确

printf STDERR ("%d precent complete.\n", $done/$total*100); #正确

改变默认的文件句柄

print默认输出到STDOUT,可以使用select操作符改变默认句柄 select BEDROCK;

用say来输出

say功能和print类似,但打印每行内容时会自动加入换行符。

say "@array"; #"1 2 3 4\n"

可以使用文件句柄 say BEDROCK "Hello!"; 

标量变量中的文件句柄

5.6版开始,文件句柄也可放到标量变量中,而不必非得使用裸字。

open my $rock_fh, '<', 'rocks.txt'  or die "Could not open rocks.txt: $!";

print $rocks_fh "limestone\n"; #句柄后不能加逗号,否则将打印变量。Perl根据print后面第一个参数之后有无逗号,确定是否为文件句柄。

print $rock_fh; #打印变量$rock_fh而非向文件句柄打印默认变量$_。

正确用法,用花括号括住文件句柄:print { $rock_fh},即使文件句柄保存在数组或哈希中也没问题:print {$rocks[0] } "string\n";

文件测试

操作符    意义

-r  文件或目录对目前用户或组是可读的

-w  文件或目录对目前用户或组是可写的

-x 文件或目录对目前用户或组是可执行的

-o  文件或目录由目前用户拥有

-R  文件或目录对实际用户或组是可读的

-W  文件或目录对实际用户或组是可写的

-X  文件或目录对实际用户或组是可执行的

-O  文件或目录由实际用户拥有

-e  文件或目录是存在的

-z  文件存在而且没有内容(对目录来说永远为假)

-s  文件或目录存在而且有内容,返回字节单位的文件大小

-f  是普通文件

-d  是目录

-l  是符号链接

-S  是socket类型的文件

-p  是命名管道

-b  是块设备文件

-c  是字符设备文件

-u  文件或目录设置了setuid位

-g  文件或目录设置了setgid位

-k  文件或目录设置了sticky位

-t  文件句柄是TTY设备

-T  看起来像文本文件

-B  看起来像二进制文件

-M  最后一次被修改后至今天数

-A  最后一次被访问后至今天数

-C  最后一次文件节点编号(inode)被变更后至今天数

如果文件操作符后面没有写文件名或句柄,默认操作数为$_

foreach (@lots_of_filenames) {

print "$_ is readable\n" if -r; # ir $_

}

任何接在操作符之后的,都会被当做测试目标:my $size_in_k = (-s) / 1024; #必须加括号

测试同一文件的多项属性

使用虚拟文件句柄_

if (-r $file and -w _) {

...}

可以在多条语句中使用,但要注意查询的文件不能改变。

栈式文件测试操作符

从Perl 5.10开始可以使用栈式写法将测试操作符排除一行(-w -r $file),靠近文件名的测试会先执行。

stat和lstat函数

stat函数使用文件句柄或文件名作为参数,执行失败返回空列表,成功返回含13个元素的数字列表。

my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);

$dev和$ino文件所在设备编号和文件的inode编号

$mode文件的权限位集合

$nlink文件或目录的硬链接数

$uid和$gid 数值形式的文件拥有者ID及组ID

$size字节为单位的文件大小

$atime, $mtime, $ctime三个时间戳,32位整数。

对符号链接名调用stat会返回指向对象的信息,如果需要链接本身信息,可调用lstat,返回值类同stat,如果参数不是符号链接,返回空列表。

时间函数

localtime将时间戳转换为易读的格式,在列表上下文中,返回数字元素列表my($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst) = localtime $timestamp;

$mon从0-11的月份,$year自1900年算起的年数$wday从0-6的星期$yday今年的第几天。

gmtime返回世界标准时间

time返回当前时间戳

localtime或gmtime在不提供参数时使用当前time返回的值。

按位运算操作符

& | ^ << >> ~   与 或 异或 左移 右移 取反

操作数可以是整数或字符串,结果对应为整数或字符串,Perl区分字符串和数字。

目录操作

改变当前工作目录

chdir  chdir '/etc' or die "cannot chdir to /etc:$!"; 不带参数,默认回到用户主目录。

文件名通配

命令行的文件名通配由shell处理,Perl的@ARGV得到的参数是shell展开后的文件名列表。

Perl内部展开通配模式,使用glob操作符,my @pm_files = glob '*.pm';,一次匹配多种模式,可用空格隔开 glob '.* *';。

另一种语法:使用尖括号语法实现通配my @all_files = <*>;,在进行文件名通配之前,尖括号内的Perl变量会先被展开成它们的当前值。

由于尖括号既表示从文件句柄处读取又代表文件名通配操作,所以Perl的区分原则是如果尖括号内是满足Perl标示符条件的,就作为文件句柄;否则,它就代表文件名通配操作。

目录句柄

打开opendir,读取readdir,关闭closedir。

目录句柄可以使用标量或裸字。

读取的名称列表包含了所有的文件,包括.和..,名称列表未排序。

可以使用模式匹配,获得想要的文件名 next unless $name =~ /\.pm$/; #只处理.pm结尾的文件

注意:readdir操作符返回的文件名不含路径,只是目录里的文件名。

递归访问目录

可以使用Perl自带的模块File:Find,完成目录的递归处理。

文件和目录的操作

删除文件

使用unlink操作符,并指定要删除的文件列表

unlink glob '*.o'; #glob返回列表,可以一次删除多个文件。

返回值代表成功删除的文件数目。不能用于删除目录

重命名文件

rename 'old', 'new';

也可用于不同的目录,实现移动文件的功能。

链接文件

link 'chicken', 'egg';  硬链接

symlink 'dodgson', 'carroll'; 符号链接,软链接。

创建和删除目录

mkdir 'fred', 0755 or warn "Cannot make fred directory:$!";

rmdir $dir or warn "cannot rmdir $dir: $!\n"; 仅能删除非空目录。

修改权限

chmod 0755, 'fred', 'barney'; #返回成功更改的条目数量

修改隶属关系

chown 1004, 100, glob '*.o'; #修改文件的拥有者及所属组,用户标识符和组标识符必须是数字形式的。

可以转换用户名和组名为编号

defined(my $user = getpwnam 'merlyn') or die 'bad user'; #用户名或组名不存在,返回undef

defined(my $group = getgrnam 'users') or die 'bad group';

chown $user, $group, glob '/home/merlyn/*'; #返回受影响的文件数量

修改时间戳

utime $now, $ago, glob '*'; #前两个参数是新的访问时间和更改时间,其余参数是要修改的文件名列表。

文件有任何的更改时,第三个时间戳(ctime)会被设为当前时刻。这个时间戳无法修改。


你可能感兴趣的:(perl,笔记)