blue1025的个人空间 https://blog.eetop.cn/mj8051 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

PERL 第12章 目录操作

已有 2289 次阅读| 2008-9-27 14:45 |个人分类:PERL

SOURCE HTML: http://socvista.com/bbs/redirect.php?fid=71&tid=932&goto=nextnewset

2008.08.25 PERL 第12章 目录操作

== 游历目录树

我们的程序带有一个默认的working directory,他是所有相对路径的参考点。
如果我们寻找一个文件“kobe”,那就意味着是“工作目录下的kobe文件”。
使用chdir可以改变工作目录。比如:
chdir "/etc" or die "can not chdir to /etc: $!";
由于chdir是一个系统请求,如果产生错误,$!会显示perl从系统处接收到的错误信息。
所有perl启动的进程都会继承这个工作目录。
如果没有指定的话,可能perl会将我们的home目录作为默认的工作目录。


== globbing

什么叫globbing? 比如
$ echo *.pm
a.pm b.pm c.pm
$
这种根据文件名pattern寻找文件并将名称扩展显示的功能就叫globbing。

== shell 提供了globbing功能

globbing功能是shell提供的,perl无需知道就可以直接使用。比如一个命令
$ perl show-args *.pm
执行结果是
one arg is a.pm
one arg is b.pm
one arg is c.pm
这个结果是怎么产生的呢?我们来看perl程序show-args
foreach $arg (@ARGV)  {
  print "one arg is $arg\n";
}

== 显式使用globbing功能

上面的例子中,我们只是提供了pattern参数。然后perl就自动调用了shell来globbing。虽然好,但是不是那么直观。那么如何显式调用这个功能呢?
my @all_files = glob "*";  # 不包括用点号开始的文件,其余的文件都包括,而且按照字母顺序排序。
my @pm_files = glob "*.pm";
my @all_files_inc_dot = glob ".* *";  # 包括所有文件

== globbing 的另一种写法<*>

用<>符号也可以完成globbing功能。看例子
my @all_files = <*>;  # glob "*" 一样
再看一个例子。
my $dir = "/etc";
my @dir_files = <$dir/* $dir/.*>;  # 和glob "* .*"一样

== 如何判断<>是一个glob还是一个file handle

如果<>中的内容是一个identifier,那么这就是一个file handle read。否则就是一个glob。比如
my @files = <FRED>; #一个filehandle read
my @files = <FRED/*>; # 一个glob

== 如何明确指定一个 filehandle read

方法:使用readline。
1. my @lines = readline FRED;
2. my @lines = readline $name;

== 用perl实现glob的方法:Directory handle

directory handle 和 file handle 有一些类似的地方,比如:
opendir - - open
readdir - - readline
closedir - - close

== 用dir handle实现 glob 的典型案例

我们来看一个例子,这个例子和 glob "* .*" 等效。
opendir DH, "/etc"
  or die "Can  not open /etc : $!";
foreach $file (readdir DH) {
  print "$file \n";
}
我们来看一个例子,这个例子和 glob "*.pm" 等效。
while ($name = readdir DIR) {
  next unless $name =~ /\.pm$/;
  ... more processing ...
}
我们来看一个例子,这个例子和 glob "*" 等效。
next if $name =~ /~\./;
我们来看一个例子,这个例子跳过那两个特殊文件。
next if $name eq "." or $name eq "..";

== readdir 只能获得local path

所以如果要获得全局路径要这样做。
opendir DIR, $dirname or die "Cannot open $dirname: $! \n";
while (my $name = readdir DIR) {
  $name = "$dirname/$name";
  ... more processing ...
}

== 目录的recursive遍历

可能最初的时候用不着这个功能。但是我们必须知道 Perl 提供了一个库的调用,叫做 File::Find,他能让你使用 recursive directory processing。实践证明,很多人会经常用到这个功能。

== 删除文件
unlink "filea", "fileb", "filec";

== 删除一个模式的多个文件
unlink glob "*.o";

== 确认删除的文件数目
my $del_no = unlink glob "*.o";  # 返回值就是删除的文件数

== 逐个删除文件并获取出错信息
foreach my $file (qw(filea fileb filec)) {
  unlink $file or warn "delete $file failed: $! \n"
}

== 文件重命名
rename "old", "new";

== 文件移动(重命名的扩展)
rename "dir1/dir11/dir111/some_file", "some_file"; # 将文件移动到当前目录下

== 一个好用的重命名程序
foreach my $file (glob "*.old") {
  (my $newfile = $file) =~ s/\.old$/.new/;
  if (-e $newfile) {
    warn "...exist!";
  } elsif (rename $file, $newfile) {
    # success,
  } else {
    warn "rename failed: $! \n";
  }
}

== 创建目录
mkdir "kobe", 0755 or warn "...";

== 目录权限必须显式声明是8进制
$permissions = "0755";
mkdir $name, oct($permissions);
建议尽量显式声明。

== 删除空目录
rmdir glob "fred/*"; # 删除所有fred下的空目录
rmdir $dir;

== 删除非空目录(无子目录)
unlink glob "$temp/* $temp/.*";  # 先删除内部文件,使目录为空
rmdir $temp;

== 删除非空目录(无子目录)
使用 File:Path 提供的 rmtree 函数。

== 修改权限
chmod 0755, "file-a", "file-b";

== 修改所有权(利用ID)
my $user = 1004; # user ID
my $group = 100;  # group ID
chown $user, $group, glob "*.o";

== 修改所有权(利用name)
defined(my $user = getpwnam "merlyn") or die "no such user";
defined(my $group = getgrnam "users") or die "no such group";
chown $user, $group, glob "*.o";

== 修改 timestamp
my $now = time;
my $ago = $now - 24*60*60;
utime $now, $ago, glob "* .*";




点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 13

    粉丝
  • 16

    好友
  • 15

    获赞
  • 23

    评论
  • 2824

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-28 23:55 , Processed in 0.026597 second(s), 14 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部