2

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?

Gerry
  • 10,337
  • 3
  • 31
  • 40
kerrysugu
  • 123
  • 1
  • 1
  • 9
  • I think your logic is a little broken. Even if the mv command were to work, after the first copy of the 'tools' directory under ./file/drive_Temp/abc/, the command would throw an error for ./file/drive_Temp/def/ as the 'tools' directory would already exist. Please advise what it is you are trying to achieve? – grail Jun 12 '17 at 03:45
  • I have made changes to my question. I want to check if the folder existed, and then move the files in the directory to a new directory provided – kerrysugu Jun 12 '17 at 04:27
  • There is no need to check for existing folders, you could use `Dir` and directly grab the files within the folder that matches that pattern. Check the posted answer. – Gerry Jun 12 '17 at 04:40

1 Answers1

4

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
Gerry
  • 10,337
  • 3
  • 31
  • 40
  • @grail `file` will overwrite the one in the target directory (i.e. `./Tools`). – Gerry Jun 12 '17 at 05:03
  • @grail Thanks for pointing that out, even it is not explicitly requested by the OP, it is relevant information and should be noted and considered in the answer (at least as an alternative). – Gerry Jun 12 '17 at 05:32