栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Perl-目录操作1

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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操作符的机会

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/450893.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号