How to replicate a directory structure using xcopy in windows - windows

I have a text file containing a list of folders.My text file looks like this:
"D:\old\FOLDER1"
"D:\old\FOLDER2"
"D:\old\FOLDER3"
"D:\old\FOLDER4"
"D:\old\FOLDER5"
all these folders have subfolders and files under it
what I want to do is use xcopy to copy FOLDER1, FOLDER2 , FOLDER3 FOLDER4 and FOLDER5 replicate folders ,replicating the structure of those folders
so in output , I want to get
D:\output\bkup\FOLDER1\............Including all subfolders and files D:\output\bkup\FOLDER2\............Including all subfolders and files D:\output\bkup\FOLDER3\.......... Including all subfolders and files
D:\output\bkup\FOLDER4\............Including all subfolders and files
D:\output\bkup\FOLDER5\............ Including all subfolders and files
I have written below script which works fine for one folder
set sourceFolder="D:\old\FOLDER5"
set destinationFolder=%sourceFolder:~7,-1%
echo %destinationFolder%
xcopy /s /e /i /h /r /y %sourceFolder% "D:\output\bkup%destinationFolder%"
but since # of directories to copy is 100+ ,I like to use a for loop or pass the list of directories to copy in a text file , that's what I don't know how to handle it.
please help me ,I'm not expert in batch file writing.

You can use for /f to read (parse if needed) a textfile line by line. Use "delims=" to read the line as a whole. Don't forget to add quotes to prevent having multiple arguments and strip the quotes in the subprocedure
for /f "delims=" %%a in (yourtextfile.txt) do call :docopy "%%a"
goto :eof
:docopy
set sourceFolder=%~1
set destinationFolder=%sourceFolder:~7,-1%
echo %destinationFolder%
xcopy /s /e /i /h /r /y %sourceFolder% "D:\output\bkup%destinationFolder%"
goto :eof

try robocopy, it is more powerfull for your needs, available for XP Prof. or newer:
set "sourceFolder=D:\old\FOLDER5"
set "destinationFolder=%sourceFolder:~7,-1%"
robocopy "%sourceFolder%" "%destinationFolder%" /MIR
This makes a complete MIRror at "%destinationFolder%".
If you want to copy folders from a text file with xcopy, use the following code:
set "sourceFolder=D:\old\FOLDER5"
set "destinationFolder=%sourceFolder:~7,-1%"
for /f "usebackqdelims=" %%i in ("My File With Source Folders.txt") do xcopy /seihry "%%i" "D:\output\bkup%destinationFolder%"
Text file with source folders is "My File With Source Folders.txt".

Taking the solution from this Microsoft forum thread:
To copy folder structure of another without copying files.
Here "ProjectsX" folder is replaced into "ProjectsY" - within SVN directory
/E - include empty directories
/XF * - all files are excluded
/XD ".svn" "obj" - specified directories are excluded
D:\SVN>robocopy ProjectsX ProjectsY /E /XF * /XD ".svn" "obj"
Thanks to the hint to robocopy in the previous answer by Endoro. But you don't need mirroring for this really.

Related

How to list all folders on specified drives with folder name first then gap then full path to folder?

dir i:\ j:\ k:\ /b /s /a:-D >c:\Users\Jason\Desktop\allFolderFilesOn_I_J_K.txt
This works great, but I am after a custom output, foldername full_path
Is this possible and if so how do I achieve this?
If I understand correctly, you don't want any files, but for every folder instead of C:\windows\system32 you want an output like system32 C:\Windows\
This can be done with the following command:
(for /d /r "D:\" %a in (*) do #echo %~nxa %~dpa)>c:\Users\Jason\Desktop\allFolderFilesOn_I_J_K.txt
where /d means "Directories only"
/r "Recursive" ("down the folder tree")
"D:\" the starting point
%~nxa the last element (the folder name)
%~dpa the drive/path to the folder
Note: this is command line syntax. For use in a batch file, replace each % with %%

Copy files matching string(s) in a text file out of many subfolders with folder structure to another destination folder

I have a lot of image files in a folder structure like this:
/Foldername1 (hohe Auflösung)/PictureRANDOMNAME1-FB.jpg
/Foldername1 (hohe Auflösung)/PictureRANDOMNAME2-FB.jpg
[...]
/Foldername2 (hohe Auflösung)/PictureRANDOMNAME1-SW.jpg
/Foldername2 (hohe Auflösung)/PictureRANDOMNAME2-SW.jpg
[...]
/Foldername3 (hohe Auflösung)/PictureRANDOMNAME1-SP.jpg
/Foldername3 (hohe Auflösung)/PictureRANDOMNAME2-SP.jpg
[...]
Now I have a filelist.txt with a list of some of these image files, like this:
PictureRANDOMNAME1, PictureRANDOMNAME3, [...]
I would like to copy all images matching the string(s) in the text file list out of all subfolders to a new destination (not moving them) while keeping the folder structure.
Maybe I need a batch file that I just copy into the main folder with all the subfolders, together with a filelist.txt, execute it and get the same folder structure but only with the wanted files on another destination.
Special about this might be the spaces in the paths and the umlauts.
Sorry for my bad english. I honestly tried my best. Maybe some native speaker could help editing to be more understandable.
#echo off
setlocal
:: This copies the tree structure from sourcedir to destdir
xcopy /t /e sourcedir destdir
:: This reads the filenames and copies the required files
for /f "delims=" %%a in (filelist.txt) do (
for %%b in (%%a) do xcopy /s /e sourcedir\%%b* destdir
)
%%a acquires the lines from the file. Since each line is comma-separated, %%b will execute xcopy on each name on the line.
You could add >nul to the end of the xcopy lines to suppress reporting if you like.
Please note that / indicates a switch in winbatch - \ is the directory-separator.
This procedure is untested. I suggest you try it against a small dummy subdirectory tree to verify it before relying on it for your live data.

How to exclude sub-directory from cacls processing in batch file

Suppose I have a directory myDir tree with many nested sub-directories. I grant full access to this directory with all its files and nested sub-directories to myUser with command: cacls myDir /T /E /G myUser:F
So far, so good.
Now I have a sub-directory myDir/A/B/C which I would like to exclude from the cacls processing. That is, I would not like to grant myUser access to this sub-directory.
What would you suggest?
The simplest way is just to move this folder to another place before running cacls and move it back after that. Does it make sense?
Inherited folder permissions are displayed as:
OI - Object inherit - This folder and files. (no inheritance to subfolders)
CI - Container inherit - This folder and subfolders.
IO - Inherit only - The ACE does not apply to the current file/directory
These can be combined as folllows:
(OI)(CI) This folder, subfolders, and files.
(OI)(CI)(IO) Subfolders and files only.
(CI)(IO) Subfolders only.
(OI) (IO) Files only.
So BUILTIN\Administrators:(OI)(CI)F means that both files and Subdirectories will inherit 'F' (Fullcontrol)
similarly (CI)R means Directories will inherit 'R' (Read folders only = List permission)
To actually change the inheritance of a folder/directory use iCACLS /grant or iCACLs /deny
You need to generate a list of files to be processed and exclude the ones you don't want since CACLS doesn't allow filtering.
Here, I use "dir" to generate the list of files to process.
You could use "forfiles" as well.
(You can make the script more compact using pipes, but I used temporary files instead just to make it more clear).
#echo off
setlocal
set TMPFILE=%TEMP%\dirs.txt
set TMPFILE2=%TEMP%\dirs2.txt
#rem Generate the list of dir names to be processed
dir "%~1" /ad /s /b /p > %TMPFILE%
#rem Filter out the unwanted ones
findstr /i /v /C:"myDir\A\B\C" < %TMPFILE% > %TMPFILE2%
#rem And execute a command on each
for /F "delims=;" %%x in (%TMPFILE2%) do call :dostuff "%%x"
goto :EOF
:dostuff
#rem do the directory itself
cacls "%~1\ /E /G myUser:F
#rem do the files
cacls "%~1\*" /E /G myUser:F
goto :EOF

copying all contents of folder to another folder using batch file?

I have a folder: C:\Folder1
I want to copy all the contents of Folder1 to another location, D:\Folder2
How do I do this using a batch file?
xcopy.exe is the solution here. It's built into Windows.
xcopy /s c:\Folder1 d:\Folder2
You can find more options at http://www.computerhope.com/xcopyhlp.htm
If you have robocopy,
robocopy C:\Folder1 D:\Folder2 /COPYALL /E
otherwise,
xcopy /e /v C:\Folder1 D:\Folder2
I see a lot of answers suggesting the use of xcopy.
But this is unnecessary. As the question clearly mentions that the author wants the content in the folder not the folder itself to be copied in this case we can do
copy "C:\Folder1\*.*" "D:\Folder2"
Thats all xcopy can be used for if any subdirectory exists in C:\Folder1
if you want remove the message that tells if the destination is a file or folder you just add a slash:
xcopy /s c:\Folder1 d:\Folder2\
RoboCopy did not work for me, and there are some good solutions here, but none explained the XCopy switches and what they do. Also you need quotes in case your path has spaces in it.
xcopy /i /e "C:\temp\folder 1" "C:\temp\folder 2"
Here is the documentation from Microsoft:
XCopy MS Documentation
/s: Specifies to include subdirectories. Excludes empty subdirectories
/e: Copies all subdirectories, even if they are empty
/i: specifies the destination is a folder (Otherwise it prompts you)
Here's a solution with robocopy which copies the content of Folder1 into Folder2 going trough all subdirectories and automatically overwriting the files with the same name:
robocopy C:\Folder1 C:\Folder2 /COPYALL /E /IS /IT
Here:
/COPYALL copies all file information
/E copies subdirectories including empty directories
/IS includes the same files
/IT includes modified files with the same name
For more parameters see the official documentation: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy
Note: it can be necessary to run the command as administrator, because of the argument /COPYALL. If you can't: just get rid of it.
#echo off
::Ask
echo Your Source Path:
set INPUT1=
set /P INPUT1=Type input: %=%
echo Your Destination Path:
set INPUT2=
set /P INPUT2=Type input: %=%
xcopy %INPUT1% %INPUT2% /y /s
On my PC, xcopy and robocopy need also the path to them, i.e. C:\Windows\System32\xcopy.exe
That's why I use simply "copy":
copy /y ....\Folder1\File.txt ....\Folder2\
#echo off
xcopy /s C:\yourfile C:\anotherfile\
This is how it is done!
Simple, right?
FYI...if you use TortoiseSVN and you want to create a simple batch file to xcopy (or directory mirror) entire repositories into a "safe" location on a periodic basis, then this is the specific code that you might want to use. It copies over the hidden directories/files, maintains read-only attributes, and all subdirectories and best of all, doesn't prompt for input. Just make sure that you assign folder1 (safe repo) and folder2 (usable repo) correctly.
#echo off
echo "Setting variables..."
set folder1="Z:\Path\To\Backup\Repo\Directory"
set folder2="\\Path\To\Usable\Repo\Directory"
echo "Removing sandbox version..."
IF EXIST %folder1% (
rmdir %folder1% /s /q
)
echo "Copying official repository into backup location..."
xcopy /e /i /v /h /k %folder2% %folder1%
And, that's it folks!
Add to your scheduled tasks and never look back.
I have written a .bat file to copy and paste file to a temporary folder and make it zip and transfer into a smb mount point,
Hope this would help,
#echo off
if not exist "C:\Temp Backup\" mkdir "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%"
if not exist "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\ZIP" mkdir "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\ZIP"
if not exist "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\Logs" mkdir "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\Logs"
xcopy /s/e/q "C:\Source" "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%"
Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\Logs"
"C:\Program Files (x86)\WinRAR\WinRAR.exe" a "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\ZIP\ZIP_Backup_%date:~-4,4%_%date:~-10,2%_%date:~-7,2%.rar" "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\TELIUM"
"C:\Program Files (x86)\WinRAR\WinRAR.exe" a "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\ZIP\ZIP_Backup_Log_%date:~-4,4%_%date:~-10,2%_%date:~-7,2%.rar" "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\Logs"
NET USE \\IP\IPC$ /u:IP\username password
ROBOCOPY "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%\ZIP" "\\IP\Backup Folder" /z /MIR /unilog+:"C:\backup_log_%date:~-4,4%%date:~-10,2%%date:~-7,2%.log"
NET USE \\172.20.10.103\IPC$ /D
RMDIR /S /Q "C:\Temp Backup_%date:~-4,4%%date:~-10,2%%date:~-7,2%"
#echo off
:: variables
echo Backing up file
set /P source=Enter source folder:
set /P destination=Enter Destination folder:
set xcopy=xcopy /S/E/V/Q/F/H/I/N
%xcopy% %source% %destination%
echo files will be copy press enter to proceed
pause

How can I move the contents of one directory tree into another?

I have a directory which contains files and a number of levels of subdirectories:
C:\Source
I would like to move the contents of C:\Source into:
C:\Destination
Requirements:
All files and all subdirectories
within C:\SourceData must be moved
I will be running the command in a
batch file
I can't use Powershell or
any other scripting languages
Attempt 0
XCOPY /E "C:\Source" "C:\Destination"
This works perfectly, but it copies instead of moves. I can't copy then delete the source as I'm moving a very large set of files and there isn't enough disk space to have two copies of them at a time.
Attempt 1
MOVE "C:\Source" "C:\Destination"
This moves the entire C:\Source directory into C:\Destination so I end up with:
C:\Destination\Source
Attempt 2
With some help from this question and accepted answer I came up with:
for /r "C:\Source" %%x in (*) do move "%%x" "C:\Destination"
This moves the files within C:\Source but not the subdirectories or their contents. Note that I used %%x instead of %x as I'm using it in a batch file.
Using FOR seems promising but I'm not sure I've used the right syntax? Have I missed something?
Attempt 3
As suggested by Nick D, I tried rename:
RENAME "C:\Source" Destination
For the example scenario I gave this works fine. Unfortunately my real Destination directory is at a different level to the Source directory and this doesn't seem to be supported:
C:\>REN /?
Renames a file or files.
RENAME [drive:][path]filename1 filename2.
REN [drive:][path]filename1 filename2.
Note that you cannot specify a new drive or path for your destination file.
I get "The syntax of the command is incorrect." errors if I try to specify a more complex destination path, for example:
RENAME "C:\Source" "C:\MyOtherDirectory\Destination"
RENAME "C:\Source" "MyOtherDirectory\Destination"
Undoubtedly use robocopy. It is a simple but brilliantly useful tool.
robocopy /move /e sourcedir destdir
This will move all the files and folders, including empty ones, deleting each original file after it has moved it.
If you don't have robocopy installed you can download it by itself or as part of a Microsoft resource kit.
Update:
Adjusted code to a. check whether folders already exist at the destination, in which case move files in that folder over (and continue traversing the source directory structure), otherwise move the folder wholesale.
At the end of the script the source folder is removed altogether to eliminate these folders which have had their files moved over to an already existent folder at the destination (meaning these folders have been emptied but not deleted at the source).
Additionally we check whether a folder is both empty and already exists at the destination in which case we do nothing (and leave the source folder to be deleted to the last line of the script). Not doing this results in "The filename, directory name, or volume label syntax is incorrect." errors.
Phew! Please let me know how you get on with this! I have tested this and it seems to be working well.
for /d /r "c:\source" %%i in (*) do if exist "c:\destination\%%~ni" (dir "%%i" | find "0 File(s)" > NUL & if errorlevel 1 move /y "%%i\*.*" "c:\destination\%%~ni") else (move /y "%%i" "c:\destination")
move /y c:\source\*.* c:\destination
rd /s /q c:\source
In response to ufukgun's answer:
xcopy C:\Source\* C:\Destination\* /s /e /i /Y
/s - Copies directories and subdirectories except empty ones.
/e - Copies directories and subdirectories, including empty ones. Same as /S /E. May be used to modify /T.
/i - If destination does not exist and copying more than one file, assumes that destination must be a directory.
/y - Suppresses prompting to confirm you want to overwrite an existing destination file.
As stated in another answer, using xcopy may be not as efficient as it would be a native move command that only changes pointers in the filesystem.
Since XCOPY works, you could use XCOPY and DELETE, it's a workaround, but should work?
on Vista use
robocopy source destination /MIR
/MIR .. mirror a complete directory tree (also deletes files in the destination)
else
xcopy
Of course you have to delete the source afterwards :)
I have a directory which contains
files and a number of levels of
subdirectories:
C:\Source
I would like to move the contents of
C:\Source into:
C:\Destination
Maybe I'm missing something, but can't you just rename the folder?
As sent on twitter:
Try combining attempt 3 with attempt 1. Rename to get the destination folder correct, then move "Destination" to the correct place.
#echo on
set SOURCE=C:\Source
set DESTINATION=C:\Destination
xcopy %SOURCE%\* %DESTINATION%\* /s /e /i /Y
PAUSE
i use batch file like this...
or simply call:
xcopy C:\Source\* C:\Destination\* /s /e /i /Y
I use a utility called xxcopy. It can move files and have many useful options, you can use it like this :
xxcopy C:\Source C:\Destination /E /RC
the options :
/E to copy everything even empty folders
/RC to remove every source file after each successful copy
you can download free copy of xxcopy for personal use from :
http://www.xxcopy.com/xcpydnld.htm
Maybe a little off-topic, but still usefull:
Some people suggest to just copy + delete the source files, but
moving files is not the same as copying + deleting!
When using the (x)copy function, you allocate new space on the same volume on a harddisk. After the copying the files, the old files (the old allocated space which was required for the files) are beign marked as deleted. While you will achieve the same result as an end-user, moving does something diffrent and more efficient.
Moving files actually only changes some records in the MFT (master file table). These changes only consist of a different path for the user to locate its files. Physically the files still remain in the same sectors on the harddisk.
If all your trying to do is move a directory and the content up one level:
MOVE folder_you_wan_to_move ..
Note that .. refers to the next directory up.
I leave this code I have written based on ljs's attempt,
It moves directory trees as Windows does, overwriting the files that already exists in destination with those in source, and avoiding the slow copy and erase method except if the destination is in a different drive.
If your S.O is not in english must change line 6 with the text used by the Dir command when it finds 0 files.
movedir.bat source_dir destination_dir
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
if %1.==. echo movedir dir1[\*] dir2 & echo move dir1 inside dir2 overwriting coincident files & echo option \* moves only dir1 content & goto end
set S=%~f1
set D=%~f2
set "noFiles= 0 File"
set "R=0" rem R is option [\*] flag
if %S:~-2%.==\.. set "S=%S:~,-2%" & set "R=1"
if not exist "%S%" goto paramERR
if not exist "%D%" goto paramERR
set "Trim=0" & set "Sc=%S%"
:LP
set /A Trim+=1 & (set "Sc=!Sc:~1!") & if NOT !Sc!.==. goto LP
if %R%==0 (if exist "%D%\%~n1%~x1" (set "D=%D%\%~n1%~x1")) else move /y "%S%" "%D%" & goto end
CALL:movefiles "%S%" "%D%"
for /D /R "%S%" %%I in (*) do (set "Way=%%~fI") & (set "Way=!Way:~%Trim%!") & if exist "%D%!Way!" (CALL:movefiles "%%I" "%D%!Way!") else (move /y "%%I" "%D%!Way!\.." > NUL)
rd /s/q "%S%" & if %R%==1 md "%S%"
goto end
:movefiles
dir %1 | find "%noFiles%" > NUL & if ERRORLEVEL 1 move /y "%~1\*.*" %2 > NUL
goto :eof
:paramERR
echo Source or Destination does not exist
:end
I think the easiest thing you could do is to modify your Attempt 2
from
MOVE "C:\Source" "C:\Destination"
to
MOVE "C:\Source\*" "C:\Destination"
KISS ;-)
Edit: this seem not to work, so my advice is to trash away the crappy DOS command line and use Cygwin with BASH as a shell! (or just add the cygwin binaries to the path so you can use mv within DOS, thus not having to change the shell as your requirements state).

Resources