Forum: Ruby How to copy the directory files only to another directory?

Posted by Love U Ruby (my-ruby)
on 2013-01-30 15:44
Hi,

Consider the below file system:


                           C:\
                           |
        --------------------------------------------------
        |                  |                |            |
     Test1               Test2            Test3        Test4
       |                   |                |            |
  ------------            c.txt           e.docx     -------------
  |          |                                       |            |
 a.pdf      b.pdf                                 m.txt          aa.pdf


Now I want to copy only regular files from the "C:\"  to "D:\document".

Can anyone help me here for the same?
Posted by Joel Pearson (virtuoso)
on 2013-01-30 15:49
You shouldn't be doing anything in "C:\".
Define "regular files"?
Posted by Love U Ruby (my-ruby)
on 2013-01-30 15:57
Joel Pearson wrote in post #1094376:
> You shouldn't be doing anything in "C:\".
> Define "regular files"?

I just want to copy only - a.pdf,b.pdf,c.txt,e.docx, m.txt,aa.pdf files 
to the folder "D:\document",not with their directories.
Posted by Joel Pearson (virtuoso)
on 2013-01-30 16:21
There are a few ways to do this, this one seems to work:

Dir.chdir 'C:/'
files = Dir.glob('**/*.pdf') +
        Dir.glob('**/*.txt') +
        Dir.glob('**/*.docx')
files.each do |fname|
  File.rename File.absolute_path(fname), 'D:/document/' + 
File.basename(fname)
end
Posted by Love U Ruby (my-ruby)
on 2013-01-30 16:29
Joel Pearson wrote in post #1094382:
> There are a few ways to do this, this one seems to work:
>
> Dir.chdir 'C:/'
> files = Dir.glob('**/*.pdf') +
>         Dir.glob('**/*.txt') +
>         Dir.glob('**/*.docx')
> files.each do |fname|
>   File.rename File.absolute_path(fname), 'D:/document/' +
> File.basename(fname)
> end

Nice idea! But as an example i used such .txt,.pdf extensions. But there 
can be various types of files, all I have to copy. But not any folder or 
directories.
Posted by Joel Pearson (virtuoso)
on 2013-01-30 16:31
The example I gave you only copies the files, not the directories. You
may get name conflicts as a result, however.
Also the example I gave will go through every directory. If you want to
limit this you'll need to be more specific in your code.

For all files, just use Dir.glob('**/*')
Posted by Love U Ruby (my-ruby)
on 2013-01-30 16:34
Joel Pearson wrote in post #1094387:
> The example I gave you only copies the files, not the directories. You
> may get name conflicts as a result, however.
> Also the example I gave will go through every directory. If you want to
> limit this you'll need to be more specific in your code.


Yes,that I understood,but What I am trying to say is in my case the file 
extension can be any thing, like .vbs,.vb,rb,xlsx etc - anything. So 
without hard-coding anyway to get any type of file names excluding their 
directories?
Posted by Joel Pearson (virtuoso)
on 2013-01-30 16:39
As above,
Dir.glob('**/*')
Posted by Love U Ruby (my-ruby)
on 2013-01-30 16:47
Joel Pearson wrote in post #1094392:
> As above,
> Dir.glob('**/*')

See my code:

C:\>irb
irb(main):001:0> Dir.pwd
=> "C:/"
<'C:/Documents and Settings/rakshiar/My Documents/userdata/Ruby')
=> 0
irb(main):003:0> Dir.pwd
=> "C:/Documents and Settings/rakshiar/My Documents/userdata/Ruby"
irb(main):004:0> Dir.glob('**/*')
=> ["Books", "Books/Beginning Ruby.pdf", "Books/Russ Olsen Eloquent 
Ruby.pdf", "
Books/Test.txt", "Books/testfile", "Scripts", "Scripts/downloadv3.rb", 
"Scripts/
FileNamerenaming.rb"]
irb(main):005:0>

Here I am also getting "Books","Scripts" - which are folder,but I don't 
want to copy them,rather their contents.
Posted by Joel Pearson (virtuoso)
on 2013-01-30 16:57
Ok, try **/*.*
Posted by Love U Ruby (my-ruby)
on 2013-01-30 17:11
Joel Pearson wrote in post #1094397:
> Ok, try **/*.*


Perfect! Thanks for your help.

C:\>irb
irb(main):001:0> Dir.chdir('C:/Documents and Settings/rakshiar/My 
Documents/us>
=> 0
irb(main):002:0> Dir.pwd
=> "C:/Documents and Settings/rakshiar/My Documents/userdata/Ruby"
irb(main):003:0> Dir.glob('**/*.*')
=> ["Books/Beginning Ruby.pdf", "Books/Russ Olsen Eloquent Ruby.pdf", 
"Books/Tes
t.txt", "Scripts/downloadv3.rb", "Scripts/FileNamerenaming.rb"]
irb(main):004:0>
Posted by Love U Ruby (my-ruby)
on 2013-01-31 15:55
Joel Pearson wrote in post #1094382:
> There are a few ways to do this, this one seems to work:
>

> files.each do |fname|
>   File.rename File.absolute_path(fname), 'D:/document/' +
> File.basename(fname)
> end


The above code during renaming deleting the file also from here 
"File.absolute_path(fname)".

Anyway to retain those files there?


Thanks
Posted by tamouse mailing lists (Guest)
on 2013-01-31 16:22
(Received via mailing list)
On Wed, Jan 30, 2013 at 10:11 AM, Arup Rakshit <lists@ruby-forum.com> 
wrote:
> irb(main):002:0> Dir.pwd
> => "C:/Documents and Settings/rakshiar/My Documents/userdata/Ruby"
> irb(main):003:0> Dir.glob('**/*.*')
> => ["Books/Beginning Ruby.pdf", "Books/Russ Olsen Eloquent Ruby.pdf",
> "Books/Tes
> t.txt", "Scripts/downloadv3.rb", "Scripts/FileNamerenaming.rb"]
> irb(main):004:0>


I think you may need/want to test for file-ness (and not directory- or
other-ness) of the files as well.

Personally, I'd go with the Find stdlib:

require 'find'

def find_files(start,&blk)
  Find.find(start) do |path|
    if File.file?(path)
      yield path
    end
  end
end

def gather_files(src,dst)
  raise "#{src} is not a directory" unless File.directory?(src)
  raise "#{dst} is not a directory" unless File.directory?(dst)
  find_files(src) {|s| File.rename(s,File.join(dst,File.basename(s)))}
end

Then call gather_files with your source directory and target
directory; in your example:

gather_files("C:\","D:\document")

should do it.
Posted by tamouse mailing lists (Guest)
on 2013-01-31 16:23
(Received via mailing list)
On Thu, Jan 31, 2013 at 8:56 AM, Arup Rakshit <lists@ruby-forum.com> 
wrote:
> The above code during renaming deleting the file also from here
> "File.absolute_path(fname)".

When you rename something, you are moving it -- if you wish to retain
those files in their original place, you need to copy them to the new
destination, not rename them.
Posted by Joel Pearson (virtuoso)
on 2013-01-31 16:33
Oops, I didn't read your request carefully enough the first time.

Here's a copy version:

require 'fileutils'
Dir.chdir 'C:/'
files = Dir.glob('**/*.*)
files.each do |fname|
  FileUtils.copy File.absolute_path(fname), 'D:/document/' +
    File.basename(fname)
end
Posted by Love U Ruby (my-ruby)
on 2013-01-31 16:57
Joel Pearson wrote in post #1094588:
> Oops, I didn't read your request carefully enough the first time.
>
> Here's a copy version:
>
> require 'fileutils'
> Dir.chdir 'C:/'
> files = Dir.glob('**/*.*)
> files.each do |fname|
>   FileUtils.copy File.absolute_path(fname), 'D:/document/' +
>     File.basename(fname)
> end


Thanks you @Joel
Posted by Joel Pearson (virtuoso)
on 2013-01-31 17:01
No problem, I learned some new stuff writing that.

But... and I cannot stress this enough... DO NOT run that on your root 
drive!
Posted by Love U Ruby (my-ruby)
on 2013-01-31 18:39
tamouse mailing lists wrote in post #1094586:
> On Wed, Jan 30, 2013 at 10:11 AM, Arup Rakshit <lists@ruby-forum.com>
> wrote:
>> irb(main):002:0> Dir.pwd
>> => "C:/Documents and Settings/rakshiar/My Documents/userdata/Ruby"
>> irb(main):003:0> Dir.glob('**/*.*')
>> => ["Books/Beginning Ruby.pdf", "Books/Russ Olsen Eloquent Ruby.pdf",
>> "Books/Tes
>> t.txt", "Scripts/downloadv3.rb", "Scripts/FileNamerenaming.rb"]
>> irb(main):004:0>
>
>
> I think you may need/want to test for file-ness (and not directory- or
> other-ness) of the files as well.
>
> Personally, I'd go with the Find stdlib:
>
> require 'find'
>


nice idea! thank you very much :)
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.