Batch file loop to grab all folders in a directory except for a certain folder - batch-file

Just wondering the best way to do this in a single batch file. I have a folder called C:\Program\Foo and I want to grab all the folders except for the testing folder inside of foo, and I want to xcopy into D:\ so in D:\ foo will be there but no test folder.
Is there a way I can loop through each folder and check for a certain name not to include?
using /Exclude would mean I would need an extra text file with "Testing" in it

I don't see why you could not create a temporary exclusion file (using a temporary folder, that is):
#ECHO OFF
FOR %%F IN ("%TEMP%\exclude.txt") DO SET tmpf=%%~sF
ECHO Testing>%tmpf%\exclude.txt
XCOPY source destination /EXCLUDE:%tmpf%\exclude.txt other options
Note: XCOPY does not recognise double quotes as path delimiters in the /EXCLUDE option and offers no alternative for specifying paths with spaces, which can be a problem on Windows XP systems. This limitation can be worked around by replacing the original path with its counterpart consisting only of short names. That is what the FOR loop in the above script does for the %TEMP% folder.

Can you use ROBOCOPY?
ROBOCOPY C:\Program\Foo D:\ * /E /XD Test
/E copies subfolders and files
/XD excludes directories

Use the EXCLUDE option and put your exclusions in that file. That will let you exclude entire directories.
http://www.pcreview.co.uk/forums/using-xcopy-backup-can-exclude-some-directories-t489674.html
xcopy "c:\document and settings" "i:\documents and settings\" /s /d /EXCLUDE:c:\a.txt
a.txt contains
\temp\
\temporary internet files\
You may need to use shorter DOS file names.

Related

How to merge a folder with another folder (with everything in it)

I would like to know how to copy a folder to another folder in a batch file.
I would like stuff with the same name to be overwritten.
Thanks.
Unless I'm missing something, the easiest way is with xcopy (provided you actually mean .bat files on Windows):
xcopy <SOURCE> <DEST> /e /d /y /h /r /c
To explain those flags:
/e: Include directories and sub directories even if empty
/d: Only copy files which have changed on SOURCE more recently than DEST
/y: Suppress prompts
/h: Also copy hidden and system files
/r: Override read-only files (e.g. ignore Read Only flag)
/c: Continue even if there are errors
Source: My standard backup script, been running every day for 6 years.
or take a look at ROBOCOPY en.wikipedia.org/wiki/Robocopy

batch script to rename files across many folders

I had a batch script that rename files inside the folder which looked like this:
ren B:\Backups\*.bc_ *.bc
Now I have files between many folders, the back up creates a new folder with a new name every day, and i need to rename files across several folders.
How can I do it? How to correctly use wild card in this case?
You cannot use a wildcard in the path in your REN statement. You will have to use some form of the FOR command.
Suppose you want to rename all *.bc_ files in the entire folder hierarchy rooted at B:\Backups.
You could use FOR /R to iterate all .bc_ files within the hierarchy and rename each file individually.
for /r "B:\Backups" %%F in (*.bc_) do ren "%%F" "%%~nF.bc"
Or you could use FOR /D /R to iterate all the folders under the root and run your wildcard REN against each of the folders
for /d /r "B:\Backups" %%F in (.) do ren "%%F\*.bc_" *.bc
Both of the commands above are designed to be used in a batch script. Change each double percent into a single percent if you want to run the command from the command line instead of from within a batch file.

CMD/batch get basename for subfolder

I want to loop through all subfolders in c:\my_folder, check if specified file exist then create (if not exist) folder in c:\copy (for example c:\copy\project1) and copy mentioned file.
Is it easy to loop through folders in batch file (for /d %variable in ("path") DO command),
but variable contains full path. For creating new folder I need only basename for subfolder.
How I can get it? Should I write another for loop when I remove other characters?
Is there any easier way?
If I understand you correctly you want just the folder name. In that case this is easy:
for /d %%d in (C:\my_folder) do echo %%~nxd
What Joey said. On the other hand, you could try a completely different approach:
XCOPY "C:\my_folder\my_file" "C:\copy" /S /I
This will copy the specified file from all subfolders of C:\my_folder to C:\copy with preserving the structure. Subfolders that do not have my_file will not be created in C:\copy. The /S switch tells XCOPY to search for my_file in subfolders. The /I parameter is there to make sure C:\copy should be a folder, before proceeding.

xcopy does not create directory structure

I have a strange problem with xcopy in Windows XP Professional. I don't know if its a stupid question as I am specifying only a file as the source, so should I even expect any other behavior ? This is it:
I am using xcopy <src> <dest> /s/y.
<src>=C:\sourcefolder\a\b\c\d\something.java and
<dest>=C:\destinationfolder.
Now xcopy copies the file but does not create the directory structure \a\b\c\d\ inside C:\destinationfolder .
what I want is C:\destinationfolder\a\b\c\d\something.java and
what I get is C:\destinationfolder\something.java
I have tried to run it in destination folder C:\destinationfolder by specifying a . for target folder
Tried it without any target in above
There is a script I have which calls xcopy iteratively so I am left with C:\destinationfolder\many java files without any directory structure.
A. Yes I have done xcopy /? to see all options
B. /T also does not create any empty directory structure
C. I can not go to source folder a\b\c\d\ and run xcopy . <dest>
UPDATE
I removed my previous answer on using ROBOCOPY. I believe the following will do what you want using XCOPY.
Assuming your folder structure is like this:
SOURCE = C:\MyJavaStuff\A\B\C\D\something.java
DEST = C:\MyDestination
Run XCOPY like this:
XCOPY C:\MyJavaStuff\something*.java C:\MyDestination /S /E
Note the * in something*.java.
The problem is that you are specifying which file to copy in the source. xcopy won't create the folder structure in this case. However, if you change your call to xcopy to
xcopy *.java C:\myfolder /s/y
it will copy the .java files and the folder structure as well. You need to specify a wildcard for this call to work as you want. If you want only to copy specific files, you will have to adjust the call to xopy, e.g.:
xcopy something.jav* C:\myfolder /s/y
Edit
You say that you get the list of files to copy from another command. If you can output this list of files in a text file, you could do the following:
FOR /F "tokens=* delims=," %F in (d:\test\list.txt) DO xcopy src\%~nxF* .\dest /S /Y
What this command does is read a text file ("d:\test\list.txt" in this case), read every line, and for each file, run xcopy, adding a wildcard at the end of the file name to make sure it creates the folder structure.
I'm assuming here that:
You can get the list of files in a text file, with only the file names (and optinally the paths)
You know the source folder ("C:\sourcefolder" in your example, the folder structure "a\b\c\d" does not need to be known) and can use it in the FOR command.
You can also use the following form:
FOR /F "tokens=* delims=," %F in ('cmd') DO xcopy src\%~nxF* .\dest /S /Y
where cmd needs to be replace with the command you use to generate your list of files to copy.
Note that if you use this FOR command in a batch file, you need to replace %F with %%F (and %~nxF* with %%~nxF*).
I had a look at the xcopy switches and you can copy the directory structure with /T, although that doesn't copy empty directories you can override this with /E. So your command would look like this:
xcopy C:\sourcefolder\a\b\c\d\something.java C:\destinationfolder /T /E /S /Y
Hope this helps!
In order to get C:\destinationfolder\a\b\c\d\something.java XCOPY needs to know how much of C:\sourcefolder\a\b\c\d\something.java to duplicate.
You can use:
C:
cd \sourcefolder
XCOPY something.java* C:\destinationfolder\ /S
Just be aware that this may have the side effect of also copying C:\sourcefolder\oops\something.java to C:\destinationfolder\oops\something.java as well as any other matches for something*.java under C:\sourcefolder\.
It seems to me that xcopy is typically used for copying directory trees, not single files (though it can work). And, xcopy will recreate the directory structure under the source folder in the target folder. If xcopy is given the /i switch, the target folder is assumed to be a directory. It will be created if it does not exist, even if there are multiple parents that need to be created.
You have C:\MyJavaStuff\A\B\C\D\something.java - that is your source. You want to end up with something.java not in C:\destinationfolder, but in C:\destinationfolder\A\B\C\D - so that is your target. You don't even have C:\destinationfolder. That is OK, with /i the entire path will be created.
xcopy /i c:\MyJavaStuff\A\B\C\D\something.java C:\destinationfolder\A\B\C\D
If something.java were the only file under C:\MyJavaStuff, you could also use
xcopy /sei c:\MyJavaStuff C:\destinationfolder
That would recreate the entire tree structure, copying your file. But if there are other files (and folders) under MyJavaStuff they would also be copied.
I have written a very similar batch file using xcopy. Perhaps what I did will help you.
This is the command I used:
xcopy "c:\Data Files\Dave's Data\*.*" "m:\Dave's Data" /R/D /E/H
In this case, Dave's Data on the source contains an entire directory tree containing at least 50,000 files & exceeding 75GB data. It runs perfectly on Windows XP
I found /T was unnecessary as the directory tree is copied. I also found /S was unnecessary as /E copied directories & sub-directories including empty ones. I included /R to copy & overwrite read only files on the destination. /H copied hidden directories. /D copied only newer files. I use this as a daily backup tool for my data.
The only problem I have is while this command will work on Windows 7 the first time, it will not work on subsequent runs when the destination directory tree exists. I suspect this is due to a privilege issue as the xcopy command will work on subsequent runs on Windows 7 within a cmd.exe window.

Move all files except some (file pattern) from a DOS command

From a DOS command I want to move all files that do not match a file name pattern.
Something like this:
For example I want to move all files that do not start with "aaa"
for %i in (*) do if not %i == aaa* move %i .\..
XCOPY is designed to work with 'exclude' lists... See below:
dir /b /a-d "source"|findstr /b "aaa" >"%temp%\aaafiles.tmp"
xcopy "source" "destination\" /exclude:%temp%\aaafiles.tmp /y
The first line performs a DIR (directory) listing of the source folder, listing files in bare format (/b) ignoring directory names (/a-d). The output is piped into the FINDSTR command.
FINDSTR looks at each filename and compares it's beginning (/b) with the string "aaa".
If the start of a filename matches the string "aaa", the filename is redirected (written) to the file aaafiles.tmp in the users TEMP directory.
The /b is vital because you don't want to exclude files such as theaaafile.txt.
The XCOPY command copies files from the source folder to the destination folder except files that are listed in aaafiles.tmp.
Prompting to overwrite existing files (/y) is turned off.
source and destination will need to be replaced your own foldernames.
Robocopy is a possibility
robocopy source destination *.* /mov /XF aaa*.*
for options see here http://technet.microsoft.com/en-us/library/cc733145.aspx
If you don't mind fiddling with the archive bit, you can use it to selectively copy and delete files based on a file mask.
Move (copy and delete) all files except those beginning w/"aaa" from current directory to "dest". May also specify full source path.
attrib +a *.*
attrib -a aaa*.*
xcopy /a [or /m] *.* dest
del /aa /q *.*
One way you can do it is create a list of the files to move in a temporary file. Then use the file in with the for command. Generate the list using findstr.
> dir/b/a-d | findstr /v aaa* > "%temp%\#movelist"
> for /f %f in (%temp%\#movelist) do move %f ...
The first command gets a list of all files (with no directories) in the current directory and then pipes the list to findstr which excludes (/v) filenames that match the pattern and puts it in the file #movelist in the temp directory. The second command just takes those results so you may do what you will with them (move it).
There's probably a better way to do it in a single command without the temporary file, I just don't know how to write it. I'm not sure how to call the dir command from within the for command. AFAIK it only takes program files that exist, not builtin commands.
In some cases it can be made more simple. For example, I had to copy recursively a bunch of directories but excluding all images (png and bmp files), so I simply created an excludeList.txt file containing:
.png
.bmp
and run
xcopy /S /I <source> <dest> /exclude:c:\excludeList.txt
It will match any file or directory containing .png, but not necessarily ending by .png. (I did not investigate if smart use of wildcards or regular expressions are possible).
It does not handle your particular example (for which you have already a good answer) but it solved my problem, and this page is what I found when I googled in search of a solution :)
Not ideal, but moving all files to the destination and moving the files back to the source is a fast way with actual move operation (no copies). Of course this assumes there are no files in destination matching the wildcard.
move source\*.* destination\ && move destination\aaa*.* source\

Resources