2013-06-27 22 views
1

我想提出一個Ruby程序,在當前目錄下的圖像分類成不同的子文件夾,例如:Ruby程序根據名稱將圖像分類到不同的目錄中?

tree001.jpg, ... tree131.jpg -> to folder "tree" 
apple01, ... apple20.jpg -> to folder "apple" 
plum1.jpg, plum2.jpg, ... plum33.jpg -> to folder "plum" 

等,程序應該會自動識別哪些文件,他們的名字是一起的。我不知道如何實現這一點。到現在爲止,我製作了一個小程序,它將命令「Dir」中的文件收集到一個數組中並按字母順序排序,以幫助通過文件名找到適當的類。有人有一個好主意嗎?

+2

我們有很多想法如何做到這一點,但沒有人會適合你的代碼」除非您向我們展示您的作品請通過編輯將您的代碼添加到問題中,我們很樂意爲您提供幫助。 –

回答

0

假設每個文件名以非數字字符,隨後是至少一個數字字符,且初始非數字字符定義的目錄你想要的文件移動到:

require 'fileutils' 

Dir.glob("*").select{|f| File.file? f}.each do |file| # For each regular file 
    dir = file.match(/[^\d]*/).to_s    # Determine destination directory 
    FileUtils.mkdir_p(dir)      # Make directory if necessary 
    FileUtils.mv(file, dir)      # Move file 
end 

創建的目錄如有必要。添加文件後,您可以再次運行它。例如,如果您稍後添加文件tree1.txt並重新運行此操作,它將被移動到,其中tree001.jpgtree131.jpg已經是。

更新:在評論,你還說,你只需要爲形成至少10組文件做到這一點下面是做到這一點的一種方式的要求:

require 'fileutils' 

MIN_GROUP_SIZE = 10 

reg_files = Dir.glob("*").select{|f| File.file? f} 
reg_files.group_by{|f| f.match(/[^\d]*/).to_s}.each do |dir, files| 
    next if files.size < MIN_GROUP_SIZE 

    FileUtils.mkdir_p(dir) 

    files.each do |file| 
    FileUtils.mv(file, dir) 
    end 
end 
+0

Thx,功能group_by是關鍵,我認爲,因爲在目錄中可能只有一個元素集合,或者兩個,三個元素集合的文件。我想選擇那些形成至少10個元素集的文件。 – Konstantin

+0

@Konstantin好的,我添加了一個更新,演示了一種方法。 –

0

我會去它是這樣的:

files = %w[ 
    tree001.jpg tree03.jpg tree9.jpg 
    apple1.jpg apple002.jpg 
    plum3.jpg plum300.jpg 
].shuffle 
# => ["tree001.jpg", "apple1.jpg", "tree9.jpg", "plum300.jpg", "apple002.jpg", "plum3.jpg", "tree03.jpg"] 

grouped_files = files.group_by{ |fn| fn[/^[a-z]+/i] } 
# => {"tree"=>["tree001.jpg", "tree9.jpg", "tree03.jpg"], "apple"=>["apple1.jpg", "apple002.jpg"], "plum"=>["plum300.jpg", "plum3.jpg"]} 

grouped_files.each do |grp, files| 
    Dir.mkdir(grp) unless Dir.exist(grp) 
    files.each { |f| FileUtils.mv(f, "#{grp}/#{f}") } 
end 

我無法測試,因爲我沒有所有的文件,也不是我願意生成它們。

重要的是group_by。它可以很容易地對類似命名的文件進行分組,從而輕鬆瀏覽它們。

對於您的情況,您需要使用Dir.glob(...)Dir.entries(...)替換指定爲files以獲取文件列表。

如果你想單獨從文件名的文件路徑,看看File.splitFile.dirnameFile.basename

File.split('/path/to/foo') 
=> ["/path/to", "foo"] 
File.dirname('/path/to/foo') 
=> "/path/to" 
File.basename('/path/to/foo') 
=> "foo" 
相關問題