【问题标题】:Directory with a number of files and subdirectories: I need to move those files into each subdirectories,as per file name in Ruby包含许多文件和子目录的目录:我需要根据 Ruby 中的文件名将这些文件移动到每个子目录中
【发布时间】:2016-09-21 05:42:52
【问题描述】:

我有一个包含许多文件和子目录的目录。我需要将这些文件移动到每个子目录中,具体取决于它们的命名。例如:

文件:

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 + a number + \s + a - .这是一种全球模式。

有什么帮助吗?

【问题讨论】:

  • 你忘了告诉我们到目前为止你做了什么。
  • 当然。我已经多次使用FileUtils 来复制文件、移动、重命名等。我真正能得到的是如何告诉 Ruby 专注于文件名,我想过一个正则表达式,但我缺乏文件之间的比较部分和文件夹名称。

标签: ruby


【解决方案1】:

不要着急,试着一步一步解决你的问题。我将通过以下步骤解决您的问题:

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:哈希。

【讨论】:

  • 优秀。感谢您的解释。我会尽力优化它:)
【解决方案2】:

这里有一个更快但不是跨平台的解决方案(假设你的工作目录是包含文件和子目录的目录),代码有点乱:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-06
    • 2021-07-12
    • 1970-01-01
    • 2011-07-07
    • 2019-11-20
    • 1970-01-01
    • 2011-09-09
    • 2017-10-08
    相关资源
    最近更新 更多