devil20 发表于 2015-12-26 07:05:00

使用Perl的File::Path模块删除非空文件夹

  之前写过用perl删除Windows下的图片缓存缩略图(Thumbs.db)
  
  不过那个只是针对单个的文件,使用unlink方法就可以了(未测试过只读文件删除的情况- -!),那如果要删除指定的一个文件夹,有三种方案:
  1、循环文件夹里面的文件,然后逐一删除,再使用rmdir删除空目录
  2、使用File模块,使用remove_tree方法
  3、调用系统命令进行删除(这个在linux下处理的较好,windows下未进行测试)
  
  我选择了第二种方案,使用File::Path模块,点击查看详情>>
  
  之前对Perl的操作符总结的并不好,这里小结一下:
  1、比较运算符

  2、逻辑运算符

  特殊说明:操作符和其命名在运算时是完全等价的,但是有不同的优先级。操作符有更高的优先级。例如 && 比 and 有更高的优先级。
  3、单引号与双引号的区别
  示例一:

   
   1: my $test = "11111";

   2: print 'test';
  得到的将是字符串”$test”
  示例二:





   1: my $test = "11111";

   2: print "$test";
  将得到变量$test的值 “11111”
  
  好的习惯是全部使用双引号(”),在需要转义的地方使用”\”
  
  
  上面是注意事项,回到写代码的初衷,为了删除某一指定文件夹下面的 “.svn”目录以及“Thumbs.db”文件。





   1: #!/usr/bin/perl

   2: use strict;

   3: use warnings;

   4: use File::Path 'remove_tree';

   5:

   6: my $path = "C:/xx/assets";

   7: my $fileCount = 0;

   8: my $folderCount = 0;

   9:

10: sub del_handler {

11:   my $path = $_;

12:   my $handle;

13:   my $subpath;

14:

15:   if (-d $path) {

16:         if (opendir($handle, $path)) {

17:             while ($subpath = readdir($handle)) {

18:               if (!($subpath =~ m/^\.$/) and !($subpath =~ m/^\.\.$/)) {

19:                     my $p = $path."/$subpath";

20:

21:                     if (-d $p) {

22:                        if ($subpath eq ".svn") {

23:                              print "delete folder .svn : $p\n";

24:                           remove_tree($p);

25:                           $folderCount++;

26:                        } else {

27:                           del_handler($p);

28:                        }

29:                     } elsif(-f $p and $subpath eq "Thumbs.db") {

30:                     unlink($p);

31:                     $fileCount++;

32:                     print "delete file Thumbs.db : $p\n";

33:                     }

34:               }

35:             }

36:             closedir($handle);

37:            }

38:   }

39: }

40:

41: del_handler($path);

42:

43: print "\n\ndelete Thumbs.db files num : $fileCount\n";

44: print "delete .svn folder num : $folderCount";
  
  
  上面的代码显示不太合理,因为把路径给写死了。如何在调用的时候,例如这样:perl del.pl path
  就是path在调用的时候才传进去呢?用$ARGV 就可以得到,调用之前判断一下。





   1: #!/usr/bin/perl

   2: use strict;

   3: use warnings;

   4: use File::Path 'remove_tree';

   5:

   6:

   7: my $fileCount = 0;

   8: my $folderCount = 0;

   9:

10: sub del_handler {

11:   my $path = $_;

12:   my $handle;

13:   my $subpath;

14:

15:   if (-d $path) {

16:         if (opendir($handle, $path)) {

17:             while ($subpath = readdir($handle)) {

18:               if (!($subpath =~ m/^\.$/) and !($subpath =~ m/^\.\.$/)) {

19:                     my $p = $path."/$subpath";

20:

21:                     if (-d $p) {

22:                        if ($subpath eq ".svn") {

23:                              print "delete folder .svn : $p\n";

24:                           remove_tree($p);

25:                           $folderCount++;

26:                        } else {

27:                           del_handler($p);

28:                        }

29:                     } elsif(-f $p and $subpath eq "Thumbs.db") {

30:                     unlink($p);

31:                     $fileCount++;

32:                     print "delete file Thumbs.db : $p\n";

33:                     }

34:               }

35:             }

36:             closedir($handle);

37:            }

38:   }

39: }

40:

41: my $path = $ARGV or die "Need target folder !\n";

42: print "Target Folder is : $path \n\n";

43:

44: del_handler($path);

45:

46: print "\n\ndelete Thumbs.db files num : $fileCount\n";

47: print "delete .svn folder num : $folderCount\n";
  使用方法(同样适用于linux)cmd切换到pl文件的目录,如c:\perlApp,C:\perlApp>perl del_svn.plC:\theme\defaultTheme\assets
  
  当然删除文件和目录,使用windows自带的dos脚本更简单一些(存为bat双击运行即可):





   1: @echo off

   2: title 文件目录SVN标志清除工具

   3:

   4: :start

   5: ::启动过程,切换目录

   6: set pwd=%cd%

   7: cd %1

   8: echo 工作目录是:& chdir

   9:

10: :input

11: ::获取输入,根据输入进行处理

12: set source=:

13: set /p source=确定要清楚当前目录下的svn信息吗?

14: set "source=%source:"=%"

15:

16: if "%source%"=="y" goto clean

17: if "%source%"=="Y" goto clean

18: if "%source%"=="n" goto noclean

19: if "%source%"=="N" goto noclean

20: if "%source%"=="q" goto end

21: if "%source%"=="Q" goto end

22: goto input

23:

24: :clean

25: ::主处理过程,执行清理工作

26: @echo on

27: @for /d /r %%c in (.svn) do @if exist %%c ( rd /s /q %%c & echo   删除目录%%c)

28: @echo off

29: echo "当前目录下的svn信息已清除"

30: goto end

31:

32: :noclean

33: ::分支过程,取消清理工作

34: echo "svn信息清楚操作已取消"

35: goto end

36:

37: :end

38: ::退出程序

39: cd "%pwd%"

40: pause
  但有时间这个bat并不能很好的完成工作,非得到未删除干净的目录下再次运行,有点繁琐(为什么出现这种现象,暂时未查到原因~ ~)
  
  DOS下还有一个Copy文件的命令也比较有用:xcopy,例如:
  xcopy D:\Aptana_work\9917\search\*\\192.168.0.178\application\search\search\   /E /Y /D
  后面/E /Y /D是参数,具体的说明可以在DOS下查看
  
  如果使用php或是python来删除文件夹和文件的话,也能做的很好,我只是当作练练手。下面是php代码,写的一个测试例子(代码规整的并不好,接触php不久..)





   1: <meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;>

   2:

   3: <?php

   4:   

   5:   function deleteDir($path) {

   6:         if (is_dir($path)) {

   7:            

   8:             echo $path.'  开始遍历文件夹...<br/>';

   9:            

10:             if ($handle = opendir($path)) {

11:               while(($file = readdir($handle)) !== false) {

12:                     

13:                     if ($file != &quot;.&quot; && $file != &quot;..&quot;) {

14:                         $path2 = $path.'/'.$file;

15:                        

16:                         if (preg_match(&quot;/.html?$/&quot;, $file)) {

17:                           deleteHandler($path2);

18:                           

19:                           if (is_dir($path2)) {

20:                                 if (rmdir($path2)) {

21:                                     echo '文件夹'.$path2.'删除成功!<br/>';

22:                                 } else {

23:                                     echo '文件夹'.$path2.'删除失败!<br/>';

24:                                 }

25:                           }

26:                         } else if (is_dir($path2)) {

27:                           if (!rmdir($path2)) {

28:                                 deleteDir($path2);   

29:                           }                           

30:                         }

31:                     }

32:                     

33:               }

34:               

35:               closedir($handle);

36:             }

37:            

38:         } else {

39:             echo '&quot;'.$path.'&quot;不是一个正确的文件夹路径...';            

40:         }

41:   }

42:   

43:   function deleteHandler($path) {

44:         if (is_dir($path)) {

45:             $handle = opendir($path);

46:            

47:             while (($file = readdir($handle)) !== false) {

48:               if ($file != '.' && $file != '..') {

49:                     $path2 = $path.'/'.$file;

50:                     

51:                     deleteHandler($path2);

52:               }

53:             }

54:            

55:             closedir($handle);

56:         } else if (is_file($path)) {

57:            

58:             if (unlink($path)) {

59:               echo '文件'.$path.'删除成功<br/>';

60:             } else {

61:               echo '文件'.$path.'删除失败<br/>';

62:             }

63:            

64:         }

65:   }

66:   

67:   deleteDir(&quot;D:/test&quot;);

68: ?>
页: [1]
查看完整版本: 使用Perl的File::Path模块删除非空文件夹