2016-09-20 85 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 
相关问题