Perl文件、目录常用操作
注意,这些操作的对象是文件名(相对路径/绝对路径),而非文件/目录句柄,句柄只是perl和文件系统中文件的关联通道,而非实体对象。 创建文件在unix类操作系统中有一个touch命令可以非常方便的创建文件,还能批量创建一些名称规律的文件。但实际上touch的主要介绍中却是"修改文件时间戳",创建文件只不过是它的辅助能力。如果没有touch命令,如何在shell环境下创建文件?最佳方式是通过重定向的方式。 在perl中没有touch类似的功能,所以原始地只能通过open打开输出类的文件句柄和输出操作来创建文件(同时也可以写入数据)。 open FH,">>/tmp/cc.log"; print FH; # 创建空文件 close FH; 如果想批量创建命名规范的文件,可以将创建操作放进循环中进行迭代。例如创建 foreach (1..10){ open FH,">cc${_}.log"; print FH; close FH; } 当然,perl可以通过system或反引号或exec来和shell进行交互。不过这样的效率毕竟一般,每次交互都fork进程并解析执行shell语句。例如: `touch dd{1..10}.log`; 但是如果想要批量创建的文件不能用一个touch(或少数几个)来创建的话,还是建议采用perl的创建方式,因为每次和shell交互touch都fork一次perl进程并解析执行shell语句,文件数量多时,这样的效率很一般。不过毕竟不太可能用到这种情形。 删除文件在unix系统里,使用rm删除文件/目录,但它内部调用的是unlink函数。 在perl中删除文件使用perl自带的unlink函数,它也会调用操作系统的unlink函数来删除文件。它可以接一个文件元素,也可以接一个列表,或者说它的参数上下文就是列表。 但是注意,unlink无法删除目录,要删除目录,见下文。 unlink @lotfiles; # 删除数组中的文件 unlink 'cc.log'; # 删除单个文件 unlink 'cc1.log','cc2.log'; # 删除文件列表 unlink qw(cc3.log cc4.log); # 删除文件列表 unlink glob dd*.log; # 通配文件名删除 关于文件名通配详细内容,见后文。 需要注意,unlink有返回值,返回的是成功删除的文件数量。 所以,unlink删除3个文件时,如果它的返回值为3,表示全删除成功了,如果返回值为0表示一个都没删除,但如果返回的是1或者2,我们就无法判断哪些文件删除成功,哪些文件删除失败。这时需要在循环中一个一个文件地迭代删除操作,并给出错误提示。 `touch dd{1..10}.log`; foreach (1..10){ unlink "dd${_}.log" and ++$count # 注意,++放在变量的前面 or warn "Can't remove file dd${_}.log: $!"; } print "removed $count filesn"; 注意上面的and语句中,自增 创建目录
例如,创建一个目录 mkdir "/tmp/test1"; mkdir; # 等价于mkdir "$_" mkdir "/tmp/test2",0755 # 权限不能加引号包围,它是8进制数值 or die "Can't create directory: $!"; 如果是使用变量传递权限位,应当使用oct()函数来保护它作为8进制数。 $perm="0755"; mkdir "/tmp/test3",oct($perm); mkdir函数无法递归创建目录。也就是说,当要创建的目录的上级目录不存在时,mkdir函数将失败。如果想递归创建目录,可使用File::Path里的make_path函数或mkpath函数,他们是等价的。 这个函数的语法是: make_path(dir1,dir2,...,{opts}) opts可以是以下几种: mask => NUM # mask和mode是同义词,NUM指定八进制权限值, mode => NUM # 这种方式指定权限值受umask影响,若目录已存在,则不修改 chmod => NUM # 直接赋予一定权限值,不受umask影响,若目录已存在,则不修改 verbose => $bool # 是否输出详细信息,默认啥也不输出 error => $err owner => $owner # 这3条都表示为创建的目录设置所有者,如果已存在,则不设置 user => $user # 可以使用username,也可以使用uid,但如果username无法 uid => $uid # 映射为uid,或者uid不存在,或者无权限的时候,将报错 group => $group # 设置所属组,处理方式和上面所有者的处理方式一样 use File::Path qw(make_path); make_path "/test/foo/bar"; # 一次性创建3级目录 make_path "/test/foo1/bar1",{ chmod => 0777,verbose => 1 } 当然,和shell交互来创建目录也非常方便: `mkdir -p /test/a/b/c`; 删除目录
例如,删除一个目录 rmdir "/tmp/test"; 因为rmdir无法删除非空目录,所以要删除非空目录,可以采用File::Path模块的rmtree函数。 rmtree的语法: rmtree($dir1,$dir2,%opt) opts可以是以下几种: verbose => $bool # 是否显示删除信息,默认啥也不显示 safe => $bool # 删除时,跳过无法删除的对象。例如虚拟文件系统(VMS,如/proc)下有很多是无法删除的 keep_root => $bool # 设置为真值时,保留顶级目录,也就是说自删除目录内的文件和子目录,顶级目录自身不删除 result => $res error => $err use File::Path qw(rmtree); rmtree '/test/foo1',{verbose => 1}; 由于perl无法向shell一样可以直接使用"*"通配,所以如果想删除目录内的文件和子目录,而保留foo1目录自身,应该设置keep_root选项,而不是用 rmtree '/test/foo1',{verbose => 1,keep_root => 1}; 实在想通配删除,可以使用glob来通配,关于通配,见后文: rmtree((glob '/test/foo1/*'),{verbose => 1}); 另一种保留目录自身的删除方式是遍历顶级目录,然后迭代删除遍历出来的每个子项: foreach (</test/foo1/*>){ -d $_ ? rmtree $_ : unlink $_; } 图方便的话,直接和shell交互也非常方便。 `rm -rf /test/foo1/*`; chdir切换目录
chdir /tmp or die "Can't change dir to /tmp: $!"; 修改权限
例如,设置目录、文件的权限: chmod 0700,qw(/test/foo /test/foo1/a.log); chmod 0700,'/test/foo','/test/foo1/a.log'; 修改所有者、所属组
chown 1001,1001,glob '*.log'; # 第一个1001是user位,第二个1001是group位 chown -1,1002,'a.log'; # uid不变 如果想按照用户名、组名来设置,使用getpwnam和getgrnam函数: defined(my $user = getpwnam 'longshuai') or die "bad user"; defined(my $group = getgrnam 'longshuai') or die 'bad group'; chown $user,$group,glob '*.log'; 重命名文件/目录文件名通配文件查找:关于find2perl脚本(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |