全部博文(85)
分类:
2010-01-18 18:45:59
Perl之中的File::Find模块包含有相同的功能并给你带来编程性结构方面的优势。为了展示它的工作方式,我将给出一个使用File::Find模块的脚本实例。
这个Perl脚本可以帮助你清理你的PC硬盘,这是通过寻找以.tmp, .chk或是.zip结尾的文件或是以~符号开始的文件来完成的(你可以在中看到整个脚本)。脚本将输出它找到的每一个文件的完整路径,而且在最后会显示出所占用的字节数。如果已经安装了Perl,你就可以在Windows或UNIX上运行这个脚本。注意在UNIX环境下,你必须修改脚本的第一行:改变/bin/perl路径来匹配环境中的Perl路径。在这个例子中,我假设你是在Windows环境下运行这个脚本。
当然,微软公司的GUI Find也提供了这些功能中的一部分,但我还是编写了脚本。这是由于一旦你在Perl中有了这个文件,你就可以用它来做各种事,例如寻找一个特定的模式,自动地将其删除,或将其作为另一个应用程序的输出。
我在标准Perl库和Perl函数中设置了一个模块,因此当你的机器上安装了Perl之后,所有必要的模块就都可以使用了(我从获得了Perl)。File::Find函数模仿了UNIX的find命令并将穿过一个文件树。这里是此方式的API:
Find(&yoursubroutine, ‘dir1’, ‘dir2’…);
你提供的子程序,我将在后面详细叙述。还有你希望进行搜索的目录的列表,记住这些目录将以一种深度优先方式被穿过。
我使用的另一个方式就是stat()函数(与C的同名库函数类似)。它给出各种关于将文件作为一个争议对待的信息,显示了此方式的API。
这里要注意函数返回的值位于一个列表之中,唯一一个我们感兴趣的值就是$size,它包含了给定文件的大小(用字节表示)。
所有工作都会在子程序中被执行,要记住每一次遇到一个文件时,它都会被调用,所以,我们的工作就是要判定文件名是否与我们要寻找的文件相匹配。
File::Find方式具有特殊变量,将被赋予特定的信息,显示如下:
当子程序被调用时,你就会确实位于变量$File::Find::dir的目录中。你可以在中看到,子程序使用常规表达式来与$_匹配,$_使用一个if声明来寻找我们前面详细给出的所有文件名。
如果在$_之中存储的文件名与if声 明中的五个常规表达式中的任何一个相匹配,我们就将在其下面输入代码块,常规表达式非常的简单,“.”代表一个文字上的点号而不是常规表达式中的“.”的 特殊意义。我们使用“”符号来避开特殊意义。“$”代表一个字符串最后的匹配而“^”代表与开头匹配。表A显示了我们试图将其与相对应的常规表达式相匹配 的文件。
File that ends with .zip |
/.zip$/ |
File that ends with .tmp |
/.tmp$/ |
File that ends with .TMP |
/.TMP$/ |
File that begins with ~ |
/^~/ |
File that ends with .chk |
/.chk/ |
这里要注意的是脚本对小写的tmp和大写的TMP同时进行查找,而出于效率方面的考虑,你可以将文件名改为大写并只查找TMP匹配。
最后,脚本使用stat()函数来记录所有与if声明之中的某个条件相匹配的文件所使用的字节数。如果条件符合,脚本将存储$size之中的值并将其加入到$ByteCount记录变量,如下面的代码所示:
$ByteCount += $size;
要在你的机器上运行脚本,在DOS命令提示窗口下键入下面的命令:
Perl diskrpt.pl
这里假设了你已经修改了你的PATH变量来包括可执行程序,且你已经将utility存储在名为Diskrpt.pl的文件之中。命令的输出将在DOS命令提示窗口中出现。
在后面的文章中,我将介绍到脚本的修改,例如删除某个文件类型或将结果交于另一个应用程序。
perl下的File::Find模块具有shell下的find命令的功能,下面具体看2个例子: 1,找出某个目录下面以*.old结尾的文件 #!/usr/bin/perl -w use strict; use File::Find; my $path = '/home/test/'; sub wanted { if ( -f $File::Find::name ) { if ( $File::Find::name =~ /\.old$/ ) { print "$File::Find::name\n"; } } } find( \&wanted, $path ); 2,找出某个目录下面几天前的文件 my $path = '/home/test/'; opendir DH, $path or die "cannot chdir to $path : $!"; for my $file (readdir DH) { next if $file eq "." or $file eq ".."; next if $file =~ /^\./; if (time() - (stat($path.$file))[8] > (60*60*24*7)) { print $path.$file."\n"; } } closedir DH; |