在作实验的时候,因为每次都要手工修改文件夹的名字,实在是给本身添了太多的麻烦,为了摆脱手工修改的困恼,因而产生了一个使用程序批量修改文件夹名字的好主意。为了最终实现这个目标,天然须要选择一种合适的脚本语言,刚好目前对Ruby十分感兴趣,因而“兴趣+需求”,诞生了一个不算过于丑陋的Ruby程序(自觉得)。正则表达式
(一)功能需求ide
首先来讲一下个人需求:在程序运行的根目录(记为LDAModel)下有50个子文件夹(名字分别为21-70,为何不是从1开始呢?),而每一个子文件夹下又有若干个子文件夹,其名字分为两类,分别是20和20(i),以下图所示:函数
而其中名为20的文件夹并不必定存在,若是不存在的话则在每次程序运行的时候将20(i)中的一个转换为20。测试
此外,20(i)的文件夹中的数据可能会出现错误,若是其中的文件数量小于6,则没法使用,所以应该将这类文件夹直接删除!ui
(二)代码及说明spa
接下来展现一下知足上述需求的代码:code
1 require 'fileutils' 2 def rename (folder) 3 # Dir.foreach(folder) do |file| 4 # puts file if File.directory?(file) && Dir. 5 # end 6 queryFolders = Dir.entries( folder ).delete_if {|e| e=~ /^\..*/ || !File.directory?(e)} 7 queryFolders.each{ |e| 8 tFolder = Dir.entries(e).delete_if{ |e| e=~/^\..*/} 9 tFolder.each{|model| 10 FileUtils.rm_rf("./#{e}/#{model}") if Dir.entries("./#{e}/#{model}").delete_if{|e1| e=~ /^\..*/ }.length()<6 11 } 12 # break; 13 next if tFolder.include?("20") 14 if (unRenameFolder = tFolder.each{|e| e=~ /20\(d{1,3}\)/}).length > 0 15 File.rename("./#{e}/#{unRenameFolder[0]}","./#{e}/20") 16 end 17 } 18 end 19 20 # puts File.dirname(__FILE__) 21 22 rename(File.dirname(__FILE__))
须要注意的是该代码仅在Mac系统下经过测试,其余的环境的可行性还有待证实。对象
下面再来简要的分析一下上述代码blog
这部分代码主要包括三个部分,第一部分是引用库FILEUTILS,第二部分是定义函数,第三部分则是调用函数文档
rename(File.dirname(__FILE__))
先来讲说第三部分(代码的最后一行),其中最须要说明的是__FILE__主要指的是当前文件所在的目录,而不是当前运行的目录。若是须要得到当前运行的目录,则须要使用Dir.pwd(熟悉Linux的朋友应该很熟悉吧,pwd哦,不是password哦~~嘻嘻)
接下来咱们再回头看一下函数定义部分,为了实现上述功能,首先找到第一层的子文件夹(即图中21,22,23那些文件夹),并去掉其中的隐藏内容和普通文件(咱们须要的是文件夹啊)。因而有
queryFolders = Dir.entries( folder ).delete_if {|e| e=~ /^\..*/ || !File.directory?(e)}
其中,使用正则表达式滤除隐藏文件(Mac系统下会有一些隐藏文件干扰咱们的正常操做,可是该方法是否在Windows下起做用呢?这是个人疑虑),用File.directory?滤除普通文档。在此不得不感叹,Ruby做为一门动态语言就是灵活啊,想把对象看做是字符串就是字符串,想看作是文件就是文件。正如N年前,某位张姓师兄的所说“一行代码搞定!”,古之人诚不余欺啊。
接下来就是遍历了,each解决。
接下来判断每一个文件夹中是否有6个以上的文件,若是没有则删除,对于文件夹的删除有两种,一种是Dir.rmdir(),另外一种则是本文所使用的方法—FileUtils.rm_rf,前一种只能删除空空如也的文件夹,然后者的杀伤力更大,直接斩草除根,而这正是咱们所须要的方式。
相信不少人注意到了,调用FileUtils.rm_rf和Dir.entries方法时,填充的参数时"./#{e}/#{model}",若是model是一个文件的话,为何不直接调用
FileUtils.rm_rf(model)和Dir.entries(model)
说实话,若是使用Java的话,确实只须要如此便可实现了。可是在Ruby中,通过笔者的屡次尝试,老是获得
No such file or directory
若是在此行使用Dir.pwd,能够清晰地看到当前的运行目录是LDAModel(也就是21,22它们的父目录),此时使用Dir.entries(model),至关于在
FileUtils.rm_rf("LDA/20")
Dir.entries("LDA/20")
作操做,因为这两个路径是不存在的,所以没法执行正确的代码。
虽然问题找到了,可是笔者仍然对Ruby的运行机制有不少疑问,但愿各位大牛不吝赐教~~~
最后须要说明的是,有不少书中都提到可使用Find来遍历文件。事实上,这一招实在是不知足笔者的基本需求,由于Find遍历的是文件夹下的全部文件和目录(彷佛是深度优先的,不过记不清了),所以被笔者直接无视!