由于公司需要,本人最近在学习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,便返回一个文件。
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);
输出:
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 $!;
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函数返回一个数组,下面是数组的各个元素的含义:
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"; } }