Recusively copy files of a specific pattern and recreate the folders hierarchy - windows

How can I copy a set of files by a specific pattern from a set of deeply structured folders recursively into another folder? Also I need to recreate the folder hierarchy from source folder in the target folder (only that folders, which contain copied files). I need to use standard Windows command-line tools.
This question looks like this one: How can I recursively copy files of a specific pattern into a single flat folder on Windows? ; but in my case I want to keep folder structure, so this script will not do this:
for /r %x in (*.dll, *pdb) do copy "%x" targetDir\

The decision is:
FOR /r %x in (PATTERN) DO
(if not exist TARGET_DIR%~px mkdir TARGET_DIR%~px) & (copy %~x c:\\TARGET_DIR%~px)
So, the "secret" is in %~px command which gives relative path of copied file, so we should create this relative path in target dir.

Related

Windows Script to Recursively Copy Files and add directory name prefix

I'm need a script to recursively copy a set of files from a folder and all the subfolders to a new folder. I do not want the directory structure copied. But I want to add the original directory name (not the full path) as a prefix to the copied file.
For example...copy
c:/photos/date1/photo1.jpg
c:/photos/date1/photo2.jpg
c:/photos/date1/photo3.jpg
c:/photos/date2/photo1.jpg
c:/photos/date2/photo2.jpg
c:/photos/date2/photo3.jpg
to:
c:/newfolder/date1-photo1.jpg
.....date1-photo2.jpg
.....date1-photo3.jpg
.....date2-photo1.jpg
.....date2-photo2.jpg
.....date2-photo3.jpg
I have this for loop to do the original copy which works just fine. But I am stuck at how to add the directory name as a prefix.
for /r %d in (*) do copy "%d" "x:\newfolder"
Appreciate advise/suggestions.

Copy directories if their subdirectories contain "connect.txt"

I want to copy multiple directories from one location to another location only if any of the subdirectories of those contain connect.txt file in them.
Example:
ANIMAL\DOG\CONNECT.TXT
PLANET\EARTH\CONNECT.TXT
SYSTEM\USER\ADMIN.TXT
Then I ONLY want to copy ANIMAL & PLANET directories to C:\DESKTOP.
move *\*\connect.txt C:\Desktop
This uses a regular expression which would work if you're really wanting to look only under the subdirectories of all directories at some location.

Moving files with specific file name & extension

I'd like to create a batch file under windows to move files with specific file names. I'd like to move all the files with txt extension and filename starting with "HH", and moving them only from root, sub directories excluded. And if a file with the same name is already exist in the destination directory I'd like to auto rename files instead of overwriting. Is it possible to do?
You can simply use:
move c:\HH*.txt destination_directory

Copy single file instead of entire directory in windows batch

Let's suppose that I am in some directory with two subdirectories, a and b. a has two files in it: t1.txt and t2.txt. That is, I have the following directory structure:
/.
/a
t1.txt
t2.txt
/b
I want to copy the file t1.txt from the a directory into the b directory.
I tried the following command
copy /b a/t1.txt b/t1.txt
but it copies the entire a directory into the b directory.
Why does this happen, and how can I make it so that only the t1.txt file is copied?
When copying to a new directory, you only need to specify the new directory. So
copy /b a\t1.txt b
should work.
That said, I don't think additionally specifying the file name would cause the error you've described -- the official help text says "Destination can consist of a drive letter and colon, a folder name, a file name, or a combination of these," which to me implies that how you have it is fine.
I've also reversed the slashes -- were you using forward slashes in your batch file or is that a typo in the post? Maybe that was the problem?

Recursively copy file-types from directory tree

I'm trying to find a way to copy all *.exe files (and more, *.dtd, *.obj, etc.) from a directory structure to another path.
For example I might have:
Code
\classdirA
\bin
\classA.exe
\classdirB
\bin
\classB.exe
\classdirC
\bin
\classC.exe
\classdirD
\bin
\classD.exe
And I want to copy all *.exe files into a single directory, say c:\bins
What would be the best way to do this?
Constraints for my system are:
Windows
Can be Perl, Ruby, or .cmd
Anyone know what I should be looking at here?
Just do in Ruby, using method Dir::glob :
# this will give you all the ".exe" files recursively from the directory "Code".
Dir.glob("c:/Code/**/*.exe")
** - Match all directories recursively. This is used to descend into the directory tree and find all files in sub-directories of the current directory, rather than just files in the current directory. This wildcard is explored in the example code.
* - Match zero or more characters. A glob consisting of only the asterisk and no other characters or wildcards will match all files in the current directory. The asterisk is usually combined with a file extension, if not more characters to narrow down the search.
Nice blog Using Glob with Directories.
Now to copy the files to your required directory, you need to look into the method, FileUtils.cp_r :
require 'fileutils'
FileUtils.cp_r Dir.glob("c:/Code/**/*.exe"), "c:\\bins"
I just have tested, that FileUtils.cp method will also work, in this case :
require 'fileutils'
FileUtils.cp Dir.glob("c:/Code/**/*.exe"), "c:\\bins"
My preference here is to use ::cp method. Because Dir::glob is actually collecting all the files having .exe extensions recursively, and return them as an array. Now cp method is enough here, now just taking each file from the array and coping it to the target file.
Why I am not liking in such a situation, the method ::cp_r ?
Okay, let me explain it here also. As the method name suggests, it will copy all the files recursively from the source to target directory. If there is a need to copy specific files recursively, then ::cp_r wouldn't be able to do this by its own power ( as it can't do selections by itself, which ::glob can do ). Thus in such a situation, you have to give it the specific file lists, it would then copy then to the target directory. If this is the only task, I have to do, then I think we should go with ::cp, rather than ::cp_r.
Hope my explanation helps.
From cmd command line
for /r "c:\code" %f in (*.exe) do copy "%~ff" "c:\bins"
For usage inside a batch file, double the percent signs (%% instead of %)
Windows shell (cmd) command:
for /r code %q in (*.exe) do copy "%q" c:\bin
Double the % characters if you place this in a batch file.

Resources