I’m very new to this, but here goes. I need to copy files from one place
to another, which sounds simple enough, but there a slight catch. They
are each within their own folder (e.g. C:\folder\folder1\1.txt,
C:\folder\folder2\2.txt) and I want to copy all of these files into a
single folder so they are all grouped together
From what I’ve found so far, I’ve used the following;
Note: there are around 30 of these to be copied, the 2 above are just
examples
Is there an easier way to do this, or do I need a separate line for each
file? Also please note, I do not need to dictate the name I want for the
file once it has been copied; it can remain the same as the source
Of course you don’t have to write down every file separately. Then the
whole program wouldn’t make sense, because you might as well copy the
files “by hand”.
I think the easiest way is to pass an array of the files to
FileUtils.copy. To get an array of all files inside a folder, use
“Dir[…]”:
You have to pass a certain path pattern, which is explained here:
By the way, be careful with backslashes in strings. Certain character
sequences like \n have a special meaning. So you should either escape
the backslashes (with another backslash) or replace them with normal
slashes.
On Wed, Jul 04, 2012 at 03:08:35AM +0900, Alex C. wrote:
Hi,
I’m very new to this, but here goes. I need to copy files from one place
to another, which sounds simple enough, but there a slight catch. They
are each within their own folder (e.g. C:\folder\folder1\1.txt,
C:\folder\folder2\2.txt) and I want to copy all of these files into a
single folder so they are all grouped together
MS Windows does directory expansion at the command line – right? You
could do the work at the command line, then. Given a program that takes
the names of the files you want to move, you could do something like
this:
program_name *\*.txt -d C:\new\
Use OptionParser to deal with the -d option, then just loop through ARGV
to move each file. For some example code doing stuff like this, you can
have a look at a simple little utility I wrote to change the encodings
of
filenames:
https://bitbucket.org/apotheon/charsetmove
If you go to the Source tab on that page, you can browse through the
files. The relevant code is in two files: lib/charset_move.rb and
bin/cmv. Actually, you can probably ignore the code in charset_move.rb
and just look at the cmv file, which contains all the stuff dealing with
option handling and looping through non-option command line arguments.
The only thing in charset_move that immediately strikes me as relevant
to
your situation is the FileUtils.mv method.
I hope this helps. I tried to give you enough information to make it
easy to figure the stuff out without just handing you a complete answer
so that what you learn about how to solve problems like this in Ruby
will
stick better in your brain.
Of course you don’t have to write down every file separately. Then the
whole program wouldn’t make sense, because you might as well copy the
files “by hand”.
I think the easiest way is to pass an array of the files to
FileUtils.copy. To get an array of all files inside a folder, use
“Dir[…]”:
By the way, be careful with backslashes in strings. Certain character
sequences like \n have a special meaning. So you should either escape
the backslashes (with another backslash) or replace them with normal
slashes.
Hi,
Thanks for the your help, it works great. I was using backslashes first
and it didn’t work until I changed them! Just another thing - can I add
an exception to the files to be copied? for example, if I didn’t want
the files from a certain folder to be copied over the the target path?
Thanks for the your help, it works great. I was using backslashes first
and it didn’t work until I changed them! Just another thing - can I add
an exception to the files to be copied? for example, if I didn’t want
the files from a certain folder to be copied over the the target path?
Thanks for the your help, it works great. I was using backslashes first
and it didn’t work until I changed them! Just another thing - can I add
an exception to the files to be copied? for example, if I didn’t want
the files from a certain folder to be copied over the the target path?
You use it to reject all elements from an Enumerable for which the block
is true (to be more exact: not nil or false).
As an example:
numbers = 1…10
get even numbers by rejecting all odd numbers
even = numbers.reject {|num| num.odd?}
p even
In your case you want to reject all files in a certain folder, so you
might check if the current file path begins with the folder path:
ignore_folder = ‘C:/folder/ignore’
copy_files = Dir["#{original_path}/**/."].reject do |file_path|
file_path.start_with? ignore_folder
end
However, this is not a perfect solution, because it will do an exact
string comparison rather than actually compare the paths. But it should
work for a small script.
You use it to reject all elements from an Enumerable for which the block
is true (to be more exact: not nil or false).
As an example:
numbers = 1…10
get even numbers by rejecting all odd numbers
even = numbers.reject {|num| num.odd?}
p even
In your case you want to reject all files in a certain folder, so you
might check if the current file path begins with the folder path:
ignore_folder = ‘C:/folder/ignore’
copy_files = Dir["#{original_path}/**/."].reject do |file_path|
file_path.start_with? ignore_folder
end
However, this is not a perfect solution, because it will do an exact
string comparison rather than actually compare the paths. But it should
work for a small script.
You’ve used slashes in original_path and backslashes in ignore_folder.
Even if there’s no actual error in this case, the string comparison will
fail, because “/” and “” are considered different.
What doesn’t work? If no file is copied, then it’s simply because
there’s no “FileUtils.copy”. The code above only selects the files that
should be copied.
Does file_path need to be changed to target_path, as that’s what I’ve
defined above it?
No, file_path is the block parameter referring to the current file.
correction: There’s actually a problem with a double slash. Leave out
You’ve used slashes in original_path and backslashes in ignore_folder.
Even if there’s no actual error in this case, the string comparison will
fail, because “/” and “” are considered different.
Still doesn’t work
Does file_path need to be changed to target_path, as that’s what I’ve
defined above it?
What doesn’t work? If no file is copied, then it’s simply because
there’s no “FileUtils.copy”. The code above only selects the files that
should be copied.
Does file_path need to be changed to target_path, as that’s what I’ve
defined above it?
No, file_path is the block parameter referring to the current file.
Thats what I have, and it now copies all the files, but hasn’t ignored a
file thats in D:/Stuff/Ruby/2/ - which is what I wanted…hmmph
FileUtils.copy copy_files, target_path
you need to use the array you calculated previously.
Jesus.
Thanks!
I only started looking at this yesterday and haven’t done any reading
really - just wanted something quick, so appreciate it’s been like
talking to a 2 year old.
Thats what I have, and it now copies all the files, but hasn’t ignored a
file thats in D:/Stuff/Ruby/2/ - which is what I wanted…hmmph
Leave out the trailing slash in ‘D:/Stuff/Ruby/’, it will lead to a
double slash in the file paths. I didn’t see that first.
Well, as you can see, the solution is far from perfect. What you could
do is to at least “normalize” the paths by replacing multiple slashes
and backslashes with a single slash: