• Perl语言入门笔记 第十三章 目录操作


    =pod
    第十三章    目录操作
     
    在目录树中移动:
        程序运行时会以自己的工作目录作为相对路径的起点,也就是说,当我们提及fred这个文件时,其实指的是"当前工作目录下的fred"
        chdir '/etc' or die "Cannot chdir to /etc: $!";
        如果掉用chdir时不加参数,perl会猜想你要回到自己的用户主目录并试着将工作目录设成主目录
        chdir后面跟路径不能是以~开头的
     
     文件名通配:
        文件名通配(glob)
        echo *.pl   会输出当前文件下所有.pl文件,没有.pl文件的话,就输出*.pl
        
        下面程序只是简单输出所有命令行参数:
            foreach $arg (@ARGV)
            {
                print "one arg is $arg
    ";
            }
        用的时候,perl ex13_1.pl *.pl
     输出:
     one arg is ex12_1.pl
     one arg is ex12_test.pl
     one arg is ex13_1.pl
     one arg is ex13_test.pl
     one arg is ex5_1.pl
     one arg is ex5_test.pl
     one arg is ex6_1.pl
     one arg is ex6_test.pl
     
        glob操作符
            my @all_files = glob '*'; #文件名按字母排序
            my @pm_files = glob '*.pm';
     
     文件名通配的另一种语法:
        my @all_files = <*>; #效果和这样的写法完全一致:my @all_files = glob '*';
        my @dir_files = <$dir/* $dir/.*>;
     
        
     my @files = <FRED/*>; #文件名通配操作
     my @lines = <FRED>; #从文件句柄读取
     my @lines = <$fred>; #从文件句柄读取
     my $name = 'FRED';
     my @files = <$name>; #文件名通配操作
     
     readline:
        my $name = 'FRED';
        my @lines = readline FRED; #从FRED读取
        my @lines = readline $name; #从FRED读取
     
     
     目录句柄:
        my $dir_to_process = '/etc';
        opendir my $dh, $dir_to_process or die "Cannot open $dir_to_process: $!";
        foreach $file (readdir $dh)
        {
            print "One file in $dir_to_process if $file
    ";
        }
        closedir $dh;
        也可以是裸字作为文件句柄,如DIR
        
        目录句柄遍历文件时把.,..,.xx.xx也匹配了进来,所以处理时要避开这些不合要求的文件,
     跳过.开头的文件;
        next if $name =~ /^./;
        去除.和..;
        next if $name eq '.' or $name eq '..';
     
        open my $somedir, $dirname or die "Cannot open $dirname: $!";
        while(my $name = readdir $somedir)
        {
            next if $name =~ /^./; #跳过名称以点开头的文件
            $name = "$dirname/$name"; #拼合为完整的路径
            next unless -f $name and -r $name; #只需要可读的文件
        }
        为了让程序更具有可移植性,可以用File::Spec::Functions模块构造用于本地系统的合适文件名:
            use File::Spec::Functions;
            opendir my $somedir, $dirname or die "Cannot open $dirname: $!";
            while(my $name = readdir $somedir)
            {
                next if $name =~ /^./;
                $name = catfile($dirname, $name);
                next unless -f $name and -r $name;
            }
     
        若是没有接上路径,文件测试操作符会在当前目录下查找文件,而不是在$dirname制定的目录下,这是使用目录句柄时最常犯的错误。
     
     递归访问目录:
        CPAN上的File::Find::Rule和File::Finder,都在File::Fine基础上的,提供了更为直观,易用的用户界面
        
     文件和目录的操作:
        删除文件:
            unlink操作符,指定要删除的文件列表
            unlink 'slate', 'bedrock', 'lava'; #这会把三个文件放进粉碎机,从此消失在系统中。
            
            unlink glob '*.o'; #glob得到一个列表,unlink删除一个列表
     
            unlink的返回值是代表成功删除的文件数目。
            
            my $successful = unlink "slate", "bedrock", "lava";
            print "I deleted $successful file(s) just down
    ";
    
            foreach my $file (qw(slate bedrock lava))
            {
                unlink $file or warn "failed on $file: $!
    ";
            }
     
     重命名文件:
        rename 'old', 'new';
        rename 'over_there/some/place/some_file' => 'some_file';
     
        和大部分调用操作系统功能的函数一样,rename执行失败时返回假,并将操作系统返回的错误信息存到$!里,从而让你可以用ordie或orwarn来向用户汇报问题。
     
        批量将.old结尾的文件名改为以.new结尾:
            foreach my $file (glob "*.old")
            {
                my $newFile = $file;
                $newFile =~ s/.old$/.new/;
                if(-e $newFile)
                {
                    warn "Can't rename $file to $newFile: $newFile exists
    ";
                }
                elsif(rename $file => $newFile)
                {
                    #改名成功,什么都不需要做
                }
                else
                {
                    warn "rename $file to $newFile failed: $!
    ";
                }
            }
     
     
     链接与文件:
        mounted volume
        
        link 'chicked', 'egg'
            or warn "Can't link chicked to egg: $!";
     
        软链接:   
            symlink 'dodgson', 'carroll'
                or warn "Can't symlink dodgson to carroll: $!";
        
        要取得符号链接指向的位置,请使用readlink函数,他会返回符号链接指向的位置,如果参数不是符号链接,则返回undef:
            my $where = readlink 'carrol'; #得到'dodgson'
            my $perl = readlink '/usr/local/bin/perl'; #告诉你实际的perl程序究竟躲在何处
        这两种链接都可以用ulink移除,你现在该了解它取这个名字的含义,unlink只是从目录里移除该文件名的链接条目,并将它的链接数递减,必要时再释放inode
     
     创建和删除目录:
        要在现有的目录下创建目录是件容易的事,只需调用mkdir函数即可:
            mkdir 'fred', 0755 or warn "Cannot make fred directory: $!";
     
            mkdir $name, oct($permissions);
     
            my ($name, $perm) = @ARGV;
            mkdir $name, oct($perm) or die "Cannot create $name: $!";
     
        
     删除目录:
        my $temp_dir = "/tmp/scratch_$$";
        mkdir $temp_dir, 0700 or die "Cannot create $temp_dir: $!";
        #将临时目录$temp_dir作为所有临时文件存放的场所
        ...
        unlink glob "$temp_dir/* $temp_dir/.*"; #先删除文件夹中的内容
        rmdir $temp_dir;   #再删除文件夹
     
     $$:pid存在$$中
     
        如果我们在临时目录里创建了子目录,那么unlink操作符在处理它们时将会失败,rmdir也会跟着失败,请参考perl自带的File::Path模块,里面的rmtree函数提供了比较完整的解决方案。
     
     如果你去确实想要创建一个临时文件或目录,可以用perl自带的File::Temp模块
     
     
    修改权限:
        chmod 0755, 'fred', 'barney';
        和许多其他操作系统接口函数一样,chmod会返回成功更改的条目的数量,哪怕只有一个参数,它也会在失败时将$!设成合力的错误信息,第一个参数代表Unix的权限值,unix的chmod命令能接受用符号表示的权限(例如+x或go=u-w),但是chmod函数并不接受这类参数。
     
     修改隶属关系:
        只要操作系统允许,你可以用chown函数修改一系列文件的拥有者以及其所属组,拥有者和所属组会被同时更改,并且在指定时必须给出数字形式的用户标示符及组标示符。
                my $user = 1004;
                my $group = 100;
                chown $user, $group, glob '*.o';
        如果要处理的不是数字,而是像merlyn这样的字符串呢?只要用getpwnam函数将用户名转换成用户编号,再用相应的getgrnam函数把用户名转换成组编号:
                defined(my $user = getpwnam 'merlyn') or die 'bad user';
                defined(my $grpup = getgrnam 'users') or die 'bad group';
                chown $user, $group, glob '/home/merlyn/*';
                成功操作后,chown函数会返回受影响的文件数量,在错误发生时会在$!中设定出错信息。
    
    修改时间戳:
        用utime函数来修改,它的前两个阐述是新的访问时间和更改时间,其余参数就是要修改时间戳的文件名列表,时间格式采用的是内部时间戳的格式(stat和lstat函数返回值类型)
        my $now = time;
        my $ago = $now - 24 * 60 * 60; #一天的秒数
        utime $now, $ago, $glob '*'; #将最后访问时间改为当前时间,最后修改时间改为一天前
    =cut


    简单练习:

    #!/usr/bin/perl -w
    use strict;
    #use autodie;
    #use File::HomeDir; #第三方模块,不管在什么操作系统上都能进入指定用户的主目录
    
    
    system 'ls';
    
    chdir '/Users/it-0003005';
    =pod
    eval
    {
        chdir '~/';
    }; #这里有分号,eval里面的程序发生fatal error 但是并不会结束程序,还会继续执行下去
    =cut
    print "+++++++++++++++++++++++++++++++++++++++++++++++
    ";
    
    system 'ls';
    
    print "+++++++++++++++++++++++++++++++++++++++++++++++
    ";
    
    foreach my $arg (@ARGV)
    {
        print "one arg is $arg
    ";
    }
    
    print "+++++++++++++++++++++++++++++++++++++++++++++++
    ";
    
    my @allFiles = glob '*'; #取出的文件文件并没有
    
    
    foreach my $value (@allFiles)
    {
        print $value, "
    ";
    }
    
    
    &search_file('/Users', '.+.py$');
    
    sub search_file
    {
        my ($dir, $partInfo) = @_;
        #print $partInfo, "
    ";
        opendir my $dh, $dir or die "Cannot open dir $dir
    ";
        my @files = readdir $dh; #标量上下文和列表上下文
        foreach my $file (@files)
        {
            my $filePath = "$dir/$file";
            if(($file =~ m#$partInfo#i) and (-f $filePath))
            {
                print "$filePath
    ";
            }
            if((-d $filePath) and ($file ne '.') and ($file ne '..'))
            {
                &search_file($filePath, $partInfo);
            }
        }
    }
    


  • 相关阅读:
    基本算法2
    基本算法
    读书笔记 《跟老齐学python》
    python杂记 20200207 离线安装 正则
    傻傻分不清之 Cookie、Session、Token、JWT 转载:https://juejin.im/post/5e055d9ef265da33997a42cc
    并发相关 杂记
    原根
    POJ2749 Building roads
    luogu P4735 最大异或和
    SP913 QTREE2
  • 原文地址:https://www.cnblogs.com/v-BigdoG-v/p/7398611.html
Copyright © 2020-2023  润新知