I need to copy a folder matching a wildcard, for instance FOLDER_*. That folder will be in the presence of other files, so I need the command to segregate it from everything else. Also, the command needs to recursively search through the directory, and return only the FOLDER that matches the wildcard, with its contents intact. Then it needs to copy it to another folder. Any ideas? I've tried quite a few variants - here is the last thing I tried.
for /D /R %%f in (FOLDER_*) do xcopy %%f %~dp0\TestResults
Next code snippet should copy all found FOLDER_* folders including their subfolders but omits all their parent folder(s) like upfolder\ in upfolder\FOLDER_* (however could be improved to include it, of course).
for /F loop against dir /b /s /ad (a static list of subfolders) is used instead of for /D /R as the option /d /r is undocumented.
Pay your attention to recursion like FOLDER_main\FOLDER_sub1\FOLDER_sub11 etc.
Operational mkdir and xcopy commands are merely echoed for debugging purposes only:
#echo OFF
for /F "delims=" %%f in ('dir /B /S /AD FOLDER_*') do (
echo mkdir "%~dp0\TestResults\%%~nxf" 2>NUL
echo xcopy /S /E /C "%%~ff" "%~dp0\TestResults\%%~nxf\"
)
Consider adding more switches to xcopy, for instance
/H Copies hidden and system files also.
/R Overwrites read-only files.
/Y Suppresses prompting to confirm you want to overwrite an existing destination file.
Related
I want to create a script that searches a multiple directory "eg: TEST" and move it to a specific location in a folder. I have tried using the below script. It display the folder location
example:
"E:\Example\TEST"
"E:\TEST\TEST"
Please check the script i have created. Can anyone help?
#echo off
set filename=TEST
set searchPath=E:\
set Destination= E:\FOUND
FOR /R "%searchPath%" %%a in (%filename%) DO (
IF EXIST "%%~fa" (
echo "%%~fa"
)
)
move "%%~fa" "%Destination%"
There are several problems:
Since you are trying to move directories, the directory tree enumerated by for /R is modified. for/for /R however does not enumerate the directory (tree) in advance, therefore unexpected results may occur -- see the following question for details about that: At which point does for or for /R enumerate the directory (tree)?.
for or for /R accesses the file system only in case there are wildcards given in the set (that is the part in between parentheses).
It is not perfectly clear what exactly you want to accomplish:
what should happen in case of conflicting items? overwrite them or not? merge (sub-)directories?
in case of E:\TEST\TEST, do you want E:\TEST to be moved at once, so there is no more directory TEST at E:\?.
Note that the move command cannot be used because it causes trouble when moving directories and the destination directory already exists (Access is denied. errors occur).
Item 1. can be solved by a nice work-around using for /F and dir:
for /F "eol=| delims=" %%I in ('dir /B /S /A:D "E:\TEST"') do echo(%%I
This enforces the entire directory tree to be enumerated (read) before the loop iterations start.
However, this introduces another problem similar to item 2.: when a name is given for dir that matches a directory existing in the given location, its content is returned rather than all items matching that name. What I mean is the following:
dir /B /S /A:D "E:\" returns all directories (/A:D) at E:\ recursively (/S);
dir /B /S /A:D "E:\file.ext" returns all directories called file.ext, even if there is a file named E:\file.ext;
but: dir /B /S /A:D "E:\TEST" returns all sub-directories of E:\TEST, but not E:\TEST itself;
however: dir /B /S /A:D "E:\TEST*" returns all directories beginning with TEST, also those in E:\; to exactly match the name TEST, additional filtering is required (using findstr);
All this means:
for /F "eol=| delims=" %%I in ('dir /B /S /A:D "E:\TEST*" ^| findstr /I /E /C:"\\TEST"') do echo(%%I
Item 3. can only be solved by you, but to provide a complete answer, I make some assumptions:
(sub-)directories are merged, already existing items are overwritten without notice;
parent directories take precedence over sub-directories (like for /R and dir /S behave, because for every branch in a tree, they always go from higher down to lower directory levels);
Item 4. can be solved by using command robocopy together with option /MOVE instead of move.
So here is the final script:
#echo off
rem // Define constants here:
set "_PATH=E:\"
set "_NAME=TEST"
set "_DEST=E:\FOUND"
2> nul mkdir "%_DEST%"
for /F "eol=| delims=" %%I in ('
dir /B /S /A:D "%_PATH%\%_NAME%*" ^| findstr /I /E /C:"\\%_NAME%"
') do (
> nul robocopy "%%I" "%_FOUND%\%_NAME" /E /MOVE
)
The > nul portion is intended to suppress progress and log messages and to suppress The system cannot find the path specified. errors in case E:\TEST\TEST is attempted to be moved although it does no longer exist since the parent E:\TEST has alread been moved before.
I have directories like:
c:\Project\Current\stage1\somefiles and some folders
c:\Project\Current\stage2\somefiles and some folders
c:\Project\Current\stage3\somefiles and some folders
c:\Project\Current\stage4\somefiles and some folders
c:\Project\Current\stage5\somefiles and some folders
.
.
.
c:\Project\Current\stage500\somefiles and some folders
I want to create a batch file so that everything inside stage1, stage2,..., stage500 will get deleted but not any of other folders so that I can still see the above directories but empty.
Can someone please help?
Try this:
#echo off
CD c:\Project\Current /d
for /f "tokens=*" %%f in ('dir /a-d /s /b') do (
del "%%f" /q /f
)
There are three important parts:
for /f "tokens=*" %%f means we are iterating over all lines that are generated by the following command and temporarily save each line in the variable %%f for each iteration.
dir /a-d /s /b is the core of the code. This will list all files inside c:\Project\Current\ including all subfolders. /a-d means that directories will be ignored as we don't want them to be erased. /s means we are searching any subfolder. /b sets the output format to simple mode so that each line of the output will contain nothing but the full path to a file.
del "%%f" /q /f simply deletes the file which is stored in %%f. /q means "don't ask me if I'm sure, just erase it" and /f means that any file - even if it is marked as system file or as invisible or protected - will be deleted. Don't miss the quotation marks around %%f as otherwise paths containing spaces will cause trouble.
I found the answer and is very simple
for /d %%X in (c:\Project\Current*) Do (
for /D %%I in ("%%X\*") do rmdir /s/q "%%I"
del /F /q "%%X\*")
Thanks for everyone's help..
I have 100+ sub-directories all under the same folder that I'm looking to copy the newest file to backup location with the directory structure intact.
\data\sub1\newest.file -> \backup\sub1\newest.file
\data\sub1\older.file1.ignore
\data\sub1\older.file2.ignore
\data\sub2\newest.file -> \backup\sub2\newest.file
\data\sub2\older.file1.ignore
etc....
Here's what I have so far, and i can't seem to piece it together. Any help would be greatly appreciated.
#echo off
set source="c:\data"
set dest="n:\backup"
if not exist %dest% md %dest%
cd /d %source%
for /d %%x in ("%source%"/*.*) do (
if not exist "%dest%\%%x" md "%dest%\%%x"
FOR /F %%I IN ('DIR *.* /A-D /B /O-D') DO COPY %%I "%DEST%\%%X" & #ECHO %%I COPIED TO "%DEST%\%%X"
)
I would try to do this with robocopy if I were you, because this will most likely be a more robust solution.
Windows' built-in xcopy program provides a flag to include empty directories.
C:\>xcopy "%source%" "%dest%" /E
But, it sounds like you may want to only copy newer/missing files. If that is the case, then #Marged has it right. You should use robocopy.
C:\>robocopy "%source%" "%dest%" /E
Check out robocopy /? for all the details and additional commands.
The metavariable %%x in your for statement is CaSe-SeNsItIvE so you must use %%x throughout the loop, but you are using %%X in the copy statement.
Since you only want to copy the first file, you should append &goto alabelotsideoftheforloop which terminates the for..x.. after the first file has been copied.
I am trying to copy all .ini files from the Windows folder into a new folder I have already created. I need this to loop through for all users. Here is what I have but it only works for the last user, not each of them. This is a batch file.
for /r %%f in ("D:\Home\*.*\windows") do
set dir="%%d
for /r "%dir%\windows\" %%f in (*.ini) do (
copy %%f "%dir%\temp_ini"
))
pause
Please help :/ Thank you
You've got a few problems -- unterminated quote on the second line, not delaying the expansion of %dir% (and indeed, setting %dir% is unnecessary, anyway), illogical use of for /r in the first line, trying to recycle %%f in nested loops, and your *.* wildcard in the first line will only match directories containing a dot. You should also make sure the temp_ini directory is outside the scope of your search for ini files; otherwise, Windows will attempt to copy the contents of temp_ini\*.ini into itself recursively. Try this instead:
for /d %%I in ("D:\Home\*") do (
rem // create directory if not exist
if not exist "%%~I\temp_ini" md "%%~I\temp_ini"
rem // capture the output of dir /s /b
for /F "delims=" %%x in (
'dir /s /b "%%~fI\Windows\*.ini" 2^>NUL'
) do copy /y "%%~fx" "%%~I\temp_ini\"
)
pause
I need to copy a list of files in a text file to a new directory, while preserving the directory structure. My file looks like this:
F326819.B88
F326819.B89
F326819.B90
F326731.B44
F326733.B61
F326733.B62
I need a batch command that will "pick" the ones listed in the text file and copy them over to a new directory, preserving the directory structure. I tried this code but it says invalid number of parameters:
for /f "delims=" %%i in (W:\GasImages\ServiceCards\WindLake.txt) do echo D|xcopy %%i "W:\GasImages\ServiceCards" "D:\Marc\WindLake" /i /z /y /e
Any help would be appreciated.
xcopy takes in a list of source files, followed by a destination directory. When there are multiple directories passed in, it doesn't know what to do with them all.
Try this (note that this code assumes the files to copy are in C:\GasImages\ServiceCards)
#echo off
for /f "delims=" %%I in (C:\GasImages\ServiceCards\WindLake.txt) do (
xcopy "C:\GasImages\ServiceCards\%%I" "D:\Marc\Windlake\" /I /Z /Y /E
)
pause
Also, the echo D| is unnecessary with the /I flag.