Perl-目录操作1

Perl-目录操作1,第1张

Perl-目录操作1 1. 当前工作目录

程序运行时总有一个相应的工作目录,后续要做的事都是从这个目录开始
借助标准模块之一的Cwd模块,我们可以看到当前的工作目录是哪个

use v5.10;
use Cwd;
say "The current working directory is ", getcwd();

打印出来的目录应该就是程序保存的位置
如果使用相对路径打开某个文件,perl会按当前目录定位这个相对路径

比如当前工作目录是/home/fred,运行以下代码来读取文件,perl会定位到/home/fred/relative/path.txt

# relative to the current working directory
open my $fh, '<:utf8', 'relative/path.txt';

我们可以用标准模块之一的File::Spec实现相对路径和绝对路径之间的互相转换

2. 修改工作目录

可以用chdir操作符修改当前工作目录

chdir '/etc' or die "cannot chdir to /etc: $!";

由于这是一个对操作系统的调用,所以出错时会设定$!的值。如果chdir返回假,则表示修改失败,应该立即检查$!中的错误原因
由perl程序启动的所有进程都会继承perl程序的工作目录。但对于调用perl程序的进程比如shell来说,它的工作目录是无法通过perl修改的。我们可以改动当前运行程序的工作目录,但无法改动父进程的工作目录。

如果调用chdir时不加参数,perl会猜想你要回到自己的用户主目录并试着将工作目录设成主目录。这是少数省略参数,却不使用$_变量的情况直以。chdir会依次查找环境变量$ENV{HOME}或$ENV{LOGDIR}并根据相应设定行事。如果没有给出预设路径,就什么都不做(如果是windows系统,还会返回失败)

某些运行环境并未设置此类环境变量,我们可以用File::HomeDir模块协助设定chdir检查的环境变量

可以用File::HomeDir模块去往特定用户的主目录,它支持大部分操作系统

3. 文件名通配
$ echo *.pm
barney.pm dino.pm fred.pm wilma.pm

这里的echo命令其实知道此刻用了文件名通配,因为shell会先把*.pm展开成一些符合条件的文件名,然后再交给echo处理,这对perl程序来说也是一样的

foreach $arg(@ARGV){
	print "one arg is $argn";
}

运行程序时,如果只有一个带有通配符的参数,shell会先展开该通配模式,再把结果传递给程序,这样对程序来说就好像看到了多个参数

$ perl show-args *.pm
one arg is barney.pm
one arg is dino.pm
one arg is fred.pm
one arg is wilma.pm

需要注意的是,show-args完全不必了解如何进行文件名通配处理,放在@ARGV里的已经是展开好了的名称

有时候程序内部也可能需要用*.pm之类的模式,可以用glob操作符将它展开成相匹配的文件名

my @all_files = glob '*';
my @pm_files = glob '*.pm';

其中,@all_files会取得当前目录中的所有文件并按字母顺序排序,但不包括以点号开头的文件

任何能够在命令行上键入的模式都可以作为(唯一的)参数交给glob处理,如果要依次匹配多种模式,可以在参数中用空格隔开各个模式

my @all_files_including_dot = glob '.* *';

需要注意的是,在引号括住的字符串里,两个条目之间的空格是有意义的!它分隔了两个要进行文件名通配处理的条目

glob操作符的效果之所以和shell完全相同,是因为在perl5.6之前,glob只不过是在后台调用/bin/bash来展开文件名,因此文件名通配非常耗时,而且还可能在目录太大时(或别的情况下)崩溃

perl内置的glob并非唯一选择,可以用File::Glob模块提供各式兼容和扩展的文件名通配

4. 文件名通配的隐式语法

过去写的程序使用尖括号语法来调用glob的功能,看起来就跟从文件句柄中读取差不多

my @all_files = <*>; # 和这样写一样一样的 my @all_files = glob "*";

perl会把尖括号内出现的变量替换成变量的值,类似于双引号内字符串的变量内插,这表示在进行文件名通配之前,perl会把变量展开位它的当前值

my $dir = '/etc';
my @dir_files = <$dir/* $dir/.*>;

这里的$dir会被展开

假如尖括号既表示从文件句柄读取又代表文件名通配操作,那perl是如何判断取舍的呢?
如果尖括号内是满足perl标识符条件的,就作为文件句柄来读取,否则,它代表的就是文件名通配操作

my @files = ; # 文件名通配操作
my @lines = ; # 从文件句柄读取
my @lines = <$fred>; # 从文件句柄读取
my $name = 'FRED';
my @files = <$name/*>; # 通配模式

上述规则的唯一例外,就是当尖括号内仅是一个简单的标量变量(不是哈希或数组元素)时,那么它就是间接文件句柄读取(indirect filehandle read),其中变量的值就是待读取的文件句柄名称

my $name = 'FRED';
my @lines = <$name>; # 对句柄FRED进行间接文件句柄读取

perl会在编译阶段决定它时文件名通配还是从文件句柄读取,因此和变量内容无关

也可以用readline操作符执行间接文件句柄读取,让程序读起来更清楚些

my $name = 'FRED';
my @lines = readline FRED; # 从FRED读取
my @lines = readline $name; # 从FRED读取

不过因为间接文件句柄读取并不常见,并且通常也只用在简单的标量变量上,所以很少有用到readline操作符的机会

欢迎分享,转载请注明来源:内存溢出

原文地址:https://outofmemory.cn/zaji/5182612.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-19
下一篇2022-11-18

随机推荐

  • 诡计多端的0是什么意思

    诡计多端的0,指那‌‌‌‌‌‌‌些使出浑身解数勾引男性同胞的0(男同中的受)。相关词:欲罢不能的1、将计就计的1,毫无防备的1等等(活学活用)。ps:0和1是分别指男同性恋中受的一方和攻的一方。诡计多

  • 粤语扑街是什么意思

    扑街,扑街(pū jiē),源自粤语,正确的字是仆街,原本是横尸街头的意思,现用于指跌倒在马路上,所以普通话里很多时错用了“扑”去代替。仆街也有自嘲的意思,譬如“今次仆街”,指这次惨了死定了。本意是骂

    2022-12-06
    000
  • 网络用语书无店砸是什么意思

    书无店砸,即书店里没有您的书,我就把书店给砸了的缩写,通常表示此人言论极其精彩。注:这是一个时间跨度较长的延伸融合梗‌‌‌‌‌‌‌‌‌此梗来自B站沙雕网友,在一些搞笑或者比较欢乐的视频的评论区,通常会

    2022-12-06
    000
  • 一丘之貉什么意思

    一丘之貉一词最早出自《汉书·杨恽传》。杨敞是汉朝丞相杨恽的儿子,他自幼家教良好,是当朝名人。汉宣帝时,霍氏谋反,杨恽因检举有功,被封为平通侯。后来,杨恽担任中山郎后,革除贿赂弊病,得到满朝官员的称赞。

    2022-12-06
    000
  • 程咬金老婆活了多少岁

    程咬金一共有两位夫人,大夫人孙氏活到三十一岁就死了,非常可惜。后来他又娶了二夫人崔氏,本来以为两个人能够长久的在一起的,但是万万没想到,她在六十七岁的时候就死了。程咬金虽然家世比较好,权利也比较大,但

    2022-12-06
    000
  • 孙尚香是谁

    孙尚香是刘备的夫人,她也是孙坚的女儿,与孙策和孙权是兄妹关系,孙吴为了和蜀汉达成联盟,便把孙尚香许配给刘备,只是三年后孙尚香再次回到吴国,关于她的事迹也没有过多的记载,不过从这点来看孙尚香也是三国里

    2022-12-06
    000
  • 太平天国运动时间是多少

    太平天国运动的时间是1851年至1864年,发生在咸丰和同治期间,主要领导人物是洪秀全,他带领其他人组织了天平天国运动,这是对清政府和外国侵略者的反抗战争,然而在1864年太平天国遭到清政府和外强镇压

  • 陈庆之的军事成就

    说起陈庆之,相信大家多少都有听说过这个名字了,关于他的故事多少都有听说过了,在网络上也经历了不断被人神话和反驳的反复过程。但是无论南朝史书记载有多么过分和夸张,也无法抹杀陈庆之以数千之众,转战逾年,纵

    2022-12-06
    100
  • 格格和公主哪个身份高

    公主的身份更高。公主的身份更高。在古代只有皇帝的女儿才能称为公主。格格是清朝才有的称谓,在满语里面的意思是“小姐”,通常称呼亲王、贝勒、贝子的女儿。电视剧里出现皇帝的女儿叫格格是错误的叫法,皇帝的女儿

发表评论

登录后才能评论

评论列表(0条)

    保存