在作實驗的時候,因爲每次都要手工修改文件夾的名字,實在是給本身添了太多的麻煩,爲了擺脫手工修改的困惱,因而產生了一個使用程序批量修改文件夾名字的好主意。爲了最終實現這個目標,天然須要選擇一種合適的腳本語言,剛好目前對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遍歷的是文件夾下的全部文件和目錄(彷佛是深度優先的,不過記不清了),所以被筆者直接無視!