Forum: Ruby Copy all files in a directory

352d42c158e96c9fb4c0e7737cabd765?d=identicon&s=25 Charlie B. (charlie_b84)
on 2012-04-10 20:57
Still new to Ruby and feel silly having to ask such a simple question,
but I can't find any examples of this on the web.

I have files in Dir1.  I want to copy all the files, and only the files,
to Dir2.  I don't always know the name of them or their extensions, I
just want them all copied.

Is there really nothing as simple as xcopy c:\dir1\*.* c:\dir2 ??  I
can't find a wildcard argument under FileUtils.cp.  Am I missing the
painfully obvious solution here?
5ea201e2891f9908f91ba3bb45c81b22?d=identicon&s=25 Jonathan Gold (Guest)
on 2012-04-10 21:15
(Received via mailing list)
You may well get a simpler solution (and I'll be interested to see it
myself),
but fwiw, here's how I roll with this kind of problem:

    Dir.chdir( dir1 ) do
        Dir.glob( "**/*" ).select { |f| File.file?( f ) }.each do |f|
            dest = "#{dir2}/#{f}"
            FileUtils.mkdir_p( File.dirname( dest ) )
            FileUtils.cp( f, dest )
        end
    end

It's worth having a strategy for handling failures (remove partially
copied dir2
in begin/rescue, or perhaps modify the block above to detect and remove
existing
dest files, etc)

jonathan
352d42c158e96c9fb4c0e7737cabd765?d=identicon&s=25 Charlie B. (charlie_b84)
on 2012-04-10 21:19
I was afraid I'd have to resort to a loop to grab each file and move it.
I'm just shocked there isn't a one line solution to this.  When your
scripting language is more difficult and cumbersome than a 20 year old
DOS command,
that's ridiculous.
Edd558282fecea501d6e7a94a171396c?d=identicon&s=25 Ian M. Asaff (Guest)
on 2012-04-10 21:23
(Received via mailing list)
why not use system("shell cmd")?
352d42c158e96c9fb4c0e7737cabd765?d=identicon&s=25 Charlie B. (charlie_b84)
on 2012-04-10 21:24
I'm leaning toward calling xcopy but I thought there would be a ruby
equivalent to it.
233c279c012ebac792aaa805f966cbc7?d=identicon&s=25 Steve Klabnik (Guest)
on 2012-04-10 21:29
(Received via mailing list)
> Is there really nothing as simple as xcopy c:\dir1\*.* c:\dir2 ?? I
> can't find a wildcard argument under FileUtils.cp. Am I missing the
> painfully obvious solution here?

From the docs:
http://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/...

FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'

Hence, you can pass a list of things as the first argument, and it'll
work.

FileUtils.cp Dir["dir1/*"].collect{|f| File.expand_path(f)}, "dir2"

That's the shortest way I can think of.
233c279c012ebac792aaa805f966cbc7?d=identicon&s=25 Steve Klabnik (Guest)
on 2012-04-10 21:33
(Received via mailing list)
Actually, since Dir.glob taks a block, I like this better:

Dir.glob("dir1/*") {|f| FileUtils.cp File.expand_path(f), "dir2" }
352d42c158e96c9fb4c0e7737cabd765?d=identicon&s=25 Charlie B. (charlie_b84)
on 2012-04-10 21:38
FileUtils.cp works great if you know what you want to copy and if you
have relatively few items.  If you have a folder with 50 files in it,
even if you knew their names it isn't practical to use the %w to copy
them all.
352d42c158e96c9fb4c0e7737cabd765?d=identicon&s=25 Charlie B. (charlie_b84)
on 2012-04-10 21:41
Steve Klabnik gets the gold star today.  Using Dir.glob this can all be
done in one line of code.  Thank you!
8869874bd9fa5de7cc06b8ebca4d4f72?d=identicon&s=25 Alexis Al (alexis12)
on 2014-02-26 09:38
Long Path Tool deletes/unlocks, copies/renames path too long
files/folders.
B078cb4f4fb473c7a54d1fc36d10c70e?d=identicon&s=25 Regis d'Aubarede (raubarede)
on 2014-02-26 15:14
Charlie B. wrote in post #1055889:
> I'm leaning toward calling xcopy but I thought there would be a ruby
> equivalent to it.

do it yourself :

class Array
   def xcopy(dir2)
      FileUtils.cp(self,dir2)
      self.size
   end
end

and then

 Dir["*.rb"].xcopy("d:/save")
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2014-03-03 17:45
(Received via mailing list)
On Tue, Apr 10, 2012 at 9:42 PM, Charlie B. <lists@ruby-forum.com>
wrote:
> Steve Klabnik gets the gold star today.  Using Dir.glob this can all be
> done in one line of code.  Thank you!

That solution has two issues:
1. It does not filter by type.
2. It unnecessarily expands the path.

FileUtils.cp Dir["dir1/*"].select {|f| test ?f, f}, "dir2"

Or, with Pathname

FileUtils.cp Pathname.glob("dir1/*").select(&:file?), "dir2"

Cheers

robert
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.