Search code examples
rubydirectoryglobfileutils

How to get the specific files in pattern-matching directory Ruby


I would like to write a Ruby script that would find if the directory from the same pattern then copy the folders and files inside to another directory.

For example, if I want to find a pattern of directory that is:

"./file/drive_Temp/**/tools/"

it can be:

  • ./file/drive_Temp/abc/tools/
  • ./file/drive_Temp/def/tools/
  • ./file/drive_Temp/xyz/tools/

as long as the front part starts with "./file/drive_Temp/" and end with "/tools/".


what I want to do is to copy all the files that meet the pattern of the directory as mentioned to a new directory:

There might be some files in the following directory such as :

  • ./file/drive_Temp/abc/tools/aaa.txt
  • ./file/drive_Temp/abc/tools/bbb.txt
  • ./file/drive_Temp/abc/tools/ccc.txt
  • ./file/drive_Temp/def/tools/zzz.txt
  • ./file/drive_Temp/def/tools/yyy.txt
  • ./file/drive_Temp/def/tools/qqq.txt
  • ./file/drive_Temp/xyz/tools/ttt.txt
  • ./file/drive_Temp/xyz/tools/jjj.txt

those txt files would be move to directory called Tools

This is my code:

if File.directory?('./file/drive_Temp/**/tools')
    FileUtils.mv './file/drive_Temp/**/tools/*.*','./Tools'
end

Is the double asterisk not working? Because the folder could not be moved to the directory specified. Or should I use glob instead?


Solution

  • You could use Dir to get all the files within those directories, and iterate to move each of those files, like this:

    Dir["./file/drive_Temp/**/tools/*"].each do |file|
      FileUtils.mv(file, './Tools')
    end
    

    Notice that this will replace any files that already exist in ./Tools; if such behavior needs to be avoided, then you can check if the file to be moved already exists in .Tools before moving it, for example:

    target_dir = "./Tools"
    
    Dir["./file/drive_Temp/**/tools/*"].each do |file|
      if File.exist?("#{target_dir}/#{File.basename(file)}")
        # Handle file with duplicate name.
      else
        FileUtils.mv(file, target_dir)
      end
    end