2016-09-20 93 views
2

我有一個包含多個文件和子目錄的目錄。我需要將這些文件移動到每個子目錄中,具體取決於它們的命名。例如:具有多個文件和子目錄的目錄:我需要將這些文件移動到每個子目錄中,如Ruby中的文件名

文件:

Hello.doc 
Hello.txt 
Hello.xls 
This_is_a_test.doc 
This_is_a_test.txt 
This_is_a_test.xls 
Another_file_to_move.ppt 
Another_file_to_move.indd 

子目錄:

Folder 01 - Hello 
Folder 02 - This_is_a_test 
Folder 03 - Another_file_to_move 

我需要的是一個名爲Hello三個文件移動到文件夾Folder 01 - Hello;將名爲This_is_a_test的三個文件放入目錄Folder 02 - This_is_a_test,並將名爲Another_file_to_move的兩個文件放入名爲Folder 03 - Another_file_to_move的目錄中。我有數百個文件,而不僅僅是這些文件。

如可以看出,文件夾名包含在最終的文件的名稱,但在一開始有一個Folder + \s +一個number + \s +一個-。這是一種全球模式。

任何幫助?

+1

你忘了告訴我們你到目前爲止所嘗試過的。 –

+0

當然。我已經多次使用'FileUtils'來複制文件,移動,重命名等。我真正可以得到的是如何讓Ruby專注於文件名,我想過一個正則表達式,但我缺乏文件之間的比較部分和文件夾名稱。 –

回答

3

不要急於嘗試逐步解決問題。我會解決您的問題在下面的步驟:從子目錄

1.單獨的文件

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 
# TODO ... 

2.遍歷文件和檢索每個文件的基本名稱,沒有擴展

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 

files.each do |file| 
    basename = File.basename(file, '.*') 
    # TODO ... 
end 

3.找到該文件應該去的子目錄

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 

files.each do |file| 
    basename = File.basename(file, '.*') 
    subdirectory = subdirectories.find {|d| File.basename(d) =~ /^Folder \d+ - #{Regexp.escape(basename)}$/} 
    # TODO ... 
end 

4.移動文件到該目錄

require 'fileutils' 

subdirectories, files = Dir['/path/to/the/directory/*'].partition{|path| File.directory?(path)} 

files.each do |file| 
    basename = File.basename(file, '.*') 
    subdirectory = subdirectories.find {|d| File.basename(d) =~ /^Folder \d+ - #{Regexp.escape(basename)}$/} 
    FileUtils.mv(file, subdirectory + '/') 
end 

完成。但使用正則表達式查找子目錄很昂貴,我們不希望爲每個文件都執行此操作。你能優化它嗎?

提示1:交易記憶的時間。
提示2:散列。

+0

優秀。感謝您的解釋。我會盡我所能優化它:) –

0

這裏是一個快,但不能跨平臺解決方案(假設你的工作目錄是包含文件和子目錄的目錄),代碼是混亂一點點:

subdirectories = `ls -d ./*/`.lines.each(&:chomp!) 

subdirectories.each do |dir| 
    basename = dir =~ /\bFolder \d+ - (\w+)\/$/ && $1 
    next unless basename 
    `mv ./#{basename}.* #{dir}` 
end 
相關問題