Perl语言入门(10 文件+目录)

时间:2022-03-06 12:16:39

由于公司需要,本人最近在学习Perl这种脚本语言,本文是我在学习Perl的过程中总结出来的一些心得和笔记,希望能够帮助也在学习Perl的各位同僚。废话不多说直接上干货!!!

————————————————— 干货分割线 —————————————————

1.Opendir:打开文件句柄

Opendir dirhandle,directory

Dirhandle:文件句柄

directory:文件目录名字

Exp:

Opendir(TEMPDIR,’/temp’) || die $!

 

2.Readdir:读取句柄的内容(目录中的文件名)

1>.Readdir dirhandle;

在标量上下文中, r e a d d i r函数返回目录中的下一项,如果目录中没有剩下任何项目,则

返回u n d e f.。在列表上下文中, r e a d d i r返回所有的(剩余的)目录项

2>.glob pattern:

Pattern为你要匹配的文件名模式.p a t t e r n可以包含目录名和文件名的各个部分。此外,p a t t e r n可以包含以下列表列出的任何一个特殊字符。在列表上下文中, g l o b返回与模式匹配的所有文件(和目录)。在标量上下文中,每查询一次g l o b,便返回一个文件。

Perl语言入门(10 文件+目录)

PS:g l o b的模式与正则表达式的模式不同。


下面是使用g l o b与opendir/readdir/closedir 之间的某些差别:
• g l o b只能返回有限数量的文件。对于较大的目录, g l o b可能会报告“太多的文件”,但是却不能返回任何文件。
• g l o b返回模式中使用的路径名,而o p e n d i r / r e a d d i r / c l o s e d i r函数则不能。
• g l o b的运行速度通常比o p e n d i r / r e a d d i r / c l o s e d i r慢。


Glob模式的编写:
@cfiles = <*.c>;   等同于:@cfiles = glob(‘*.c’);
匹配所有文件:
匹配文件名中有.的文件:glob(“*.*”);

Exp:

#输出该路径下扩展名为txt的所有文件

my @hfiles = glob('C:/Users/Administrator/Desktop/test/*.txt');
foreach $a(@curfiles){
    print "$a\n";
}

#输出该perl文件所在路径下文件名包含t且扩展名为txt或者pl的所有文件

my @curfiles = glob('*t*.{txt,pl}');
foreach $a(@curfiles){
    print "$a\n";
}

#输出该perl文件所在路径下的所有文件,文件格式为:序号.文件名

my $count = 1;
while(my $name = glob('*')){
    print "$count . $name\n";
    $count++;
}
Exp:
这个练习展示了一个实用程序,它提示你输入一个目录名和一个模式。目录中的每个文件均被搜索,以便寻找该模式,与该模式相匹配的文件行将被输出。
#!/usr/bin/perl -w
use strict;
use warnings;
 
print "Directory to search:";
my $dir = <STDIN>; chomp $dir;
print "Pattern to look for:";
my $pat = <STDIN>; chomp $pat;
 
my ($file);
opendir(DH,$dir) or die $!;
while($file = readdir DH){
    next if(-d "$dir/$file");	#若$dir/$file是一个目录,则返回真
    if(!open(F,"$dir/$file")){
    warn "Cannot search $file:$!";
    next;
    }
    #逐行读取该文件,若能与模式匹配,则输出该文件
    while(<F>){
        if(/$pat/){
            print "$file:$_";
        }
    }
    close(F);
}
closedir(DH);

输出:

 Perl语言入门(10 文件+目录)

 

3.Closedir:关闭句柄

Closedir dirhandle;

Exp:

#!/usr/bin/perl -w
use strict;
use warnings;
 
opendir(TEMP,'C:/Users/Administrator/Desktop/Perl_Code') or die $!;
my @FILES = readdir TEMP;
closedir(TEMP);
print "@FILES  ";

输出:Perl_Code目录下的所有文件名.和..

 

4.清除目录中的.和..:

@FILES = grep(!/^\.\.?$/,readdir TEMP);

PS:对于正则表达式的说明.

/^\.\.?$/中

^:匹配字符串开头.

$:匹配字符串结尾

\.:为.(因为.为元字符,想要匹配.就得加\)

?:匹配0个或者1个

Grep:清除表达式匹配的内容

 

#获得带有特定扩展名的全部文件:

@FILES = grep(/\.txt$/i,readdir TEMP);

PS:r e a d d i r返回的文件名并不包含o p e n d i r使用的路径名。所以如下代码是错误的:

opendir( TEMP,'C:/Users/Administrator/Desktop/Perl_Code') or die $!;

while(my $file = readdir TEMP){  #能够成功的将该路径下的文件赋值给标量$file

 

#$file中只是TEMP路径下的全部文件名,所以下面这条语句并没有任何意义

open(FILEH,$file) or die $!;

print FILEH;

}

报错:Permission denied at sub.pl line 7.(遇到该报错也知道了这有可能是语法错误).


5.确定当前目录:

Cwd

Exp:

use Cwd;

print "Your current directory is:",cwd,"\n";

chdir 'test' or warn "Directory /tmp not accessible:$!";     #后面有对chdir函数的介绍

print "Your are now in:",cwd,"\n";

 

6.创建目录:

mkdir newdir,permissions;

PS:permissions为文件设置读写权限.对于D O S和Wi n d o w s用户来说,只使用0 7 5 5这个值就足够了.

Exp:

print "Directory to create?\n";

my $newdir = <STDIN>; chomp $newdir;

mkdir ($newdir,0755) or die $!;

 Perl语言入门(10 文件+目录)

7.设置文件的访问许可权:

chmod mode,list_of_files;

Chmod函数返回已经改变访问许可权的文件数量。m o d e的前面必须有一个数字0.

Exp:

chmod 0755,’file.pl’;

chmod 0644,’mydata.txt’;

 

8.删除目录:

rmdir pathname;

Exp:

print "Directory to be removed?\n";

my $baddir = <STDIN>; chomp $baddir;

rmdir ($baddir) or die $!;

PS:rmdir函数只能删除内容为空的目录.若该目录中有文件或者子文件夹则不能删除.

 

9删除指定目录中的文件:

unlink list_of_files;

unlink函数能删除l i s t _ o f _ f i l e s中的指定文件,并返回已经删除的文件数量。如果

l i s t o f f i l e s被省略,$ _中指定的文件将被删除

PS:因为不能恢复被删除的文件,所以使用此功能时要小心。

:unlink("/tmp/t1.txt", "/tmp/t2.txt");

Exp:

若不能成功删除,输出一条出错消息,显示“剩余的”文件。

#!/usr/bin/perl -w
use strict;
use warnings;
 
my @files = <*.txt>;
my $erased = unlink @files;
if($erased != @files){
    print "files failed to erase:",join(',',<*.txt>),"\n";
}

10.将当前工作目录改为n e w d i r:

chdir newdir ;

如果n e w d i r目录不存在,或者你不拥有对n e w d i r的访问权,那么c h d i r返回假。chdir对目录的改变是暂时的,一旦P e r l程序运行结束,就返回运行P e r l程序之前所在的目录(dos窗口中也可使用).

 

11.给文件或目录改名:

rename oldname,newname;

r e n a m e函数取出名字为o l d n a m e的文件,将它的名字改为n e w n a m e。如果改名成功,该函数返回真。

PS:

1.如果你设定了路径名,而不只是设定文件名,那么r e n a m e函还会将文件从一个目录移到

另一个目录,如下例所示:

rename “myfile.txt”,”/tmp/myfile.txt”;   # myfile.txt从当前目录下移至tmp目录下.

如果文件n e w n a m e已经存在,将不进行移动操作。

2.若文件在不同的文件系统上,那么r e n a m e函将不会把文件从一个目录移到另一个目录中。

 

12.了解文件的详细信息:

stat filehandle;

stat filename;

Stat函数返回一个数组,下面是数组的各个元素的含义:

 Perl语言入门(10 文件+目录)

Exp:

#!/usr/bin/perl -w
use strict;
use warnings;
 
my $f = 'temp.txt';
my @a = stat($f);
print $a[7];           #编号7用来返回文件的大小.

通常,为了清楚起见, s t a t的返回值被拷贝到标量的一个赋值列表:

($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat(“myfile”);

 

 

对目录内的所有文件重命名小程序:

EXP:

#!/usr/bin/perl -w
use strict;
use warnings;
 
my($dir,$oldpat,$newpat);
 
print "Directory:";
chomp ($dir = <STDIN>);
print "Old pattern:";
chomp ($oldpat = <STDIN>);
print "New pattern:";
chomp ($newpat = <STDIN>);
 
opendir(DIR,$dir) or die $!;
my @files = readdir DIR;
closedir(DIR);
 
my $oldname;
foreach(@files){
    $oldname = $_;	#每次遍历将一个文件名赋值给$oldname
    s/$oldpat/$newpat/;
    next if(-e "$dir/$_");  #若该文件名已存在,则跳过
    if(!rename "$dir/$oldname","$dir/$_"){
        warn "Could not rename $oldname to $_:$!";
    }else{
        print "File $oldname renamed to $_\n";
    }
}