Excluding folders from %% parameter in Windows command line - batch-file

I would like to modify the following code to better target a set of folders.
I have the following folder structure:
C:\Root\Dir1\Data, C:\Root\Dir2\Data, ...
D:\Root\Dir1\Data, C:\Root\Dir2\Data, ...
The C: contains working copies, and the D: contains backup copies to be restored on-demand. With the help of #Marged, I utilize the following batch file:
for /d %%g in ("C:\Root\*") do rd /s /q "%%g\Data"
xcopy /s /q "D:\Root" "C:\Root"
pause
I now need a way to specify %%g to exclude folders in C:\Root\*. In example, I want line 1 to delete C:\Root\Dir1\Data and C:\Root\Dir2\Data but not C:\Root\Dir3\Data. It is required to make the exclusions explicit, as the set of inclusions change. I also need line 2 to better target folders. However, I believe that can be accomplished with XCOPY's /EXCLUDE:"D:\Root\Dir3" switch.
Thank you very much for reading and in advance for any discussion! :)

... do if "%%~g" neq "C:\Root\Dir3" rd ...? – Stephan

Related

how to copy only modified files using LogFile.txt?

when it comes to creating a batch-file I would sadly call myself a newbie and therefore it's kind of difficult for me to achieve what I want on my own:
so here is how my codes look:
#ECHO OFF
for /r "C:\source" %%f in (*) do copy /y "%%f" C:\ReadyToExport
del C:\ReadyToExport\*.pdf*
for /f "delims=" %%i in ('xcopy "C:\ReadyToExport" C:\import /EXCLUDE:LogFile.log /S /E /D') do (
echo %%i >> C:\LogFile.log)
PAUSE
and here is what the code exactly does
1- for /r "C:\source" %%f in (*) do copy /y "%%f" C:\ReadyToExport
this line copies all files from source to another target folder the good thing is that this command copies all the files inside other subfolders from source and paste them into the folder C:\ReadyToExport without any subfolders.
2- del C:\ReadyToExport\*.pdf*
this command filters all the .pdf files because they are unnecessary
3-
for /f "delims=" %%i in ('xcopy "C:\ReadyToExport" C:\import /EXCLUDE:LogFile.log /S /E /D') do (
echo %%i >> C:\LogFile.log)
this command basically copies all files from "C:\ReadyToExport" into C:\import and writes the name of the recorded file in LogFile.log then the copied files will be excluded when the script runs again because I don't want to copy the files again if I already copied them before
and here is what I want to achieve:
I want to copy only modified files from the folder "C:\ReadyToExport" to the target C:\import but keep in mind that
the files in the target folder "C:\import" will be deleted but since the names of the files that have already been copied are registered in LogFile.log the files will be excluded and not copied again.
in another word: files in target file do not exist anymore but their names are written in LogFile
so is there any way to copy only modified ones? even though they don't exist in the target folder anymore? but their names are in LogFile.txt? can the script somehow write the last modified date in LogFile.txt near the file name? and then compare the date from the source? so it copies only files that have been changed and ignore all files that didn't?
p.s: using Xcopy, robocopy, etc is not a problem
any answer will be appreciated.
thnx
your method does, in fact, works so thank you so much not the way the I want with exclude:logfile.log
but this definitely worked:
robocopy C:\ReadyToExport\ C:\import /M /E
since it copies only the files that hast the attribute archivable checked in the settings.

copy files created or modified today with robocopy

I'm trying to create a batch file in Win7 that will copy any files that have been created or modified today and copy them to a destination with a similar directory structure. This is what I have so far:
set today="20180721"
robocopy "C:\temp\" "D:\backup\temp\" *.* /s /DCOPY:T /MINAGE:%today%
I know that /e copies empty directories and /xf excludes all files, but I'm not sure if that helps me. The code above seems to copy all files regardless of date, so I'm a little lost here.
Assigning quotes to your variables is not a best practice and will cause problems with some commands if you try to quote the variable later on. Regardless that was not your problem. Your problem is you need to use the /MAXAGE option. Reading the help file you should see this:
/MAXAGE:n : MAXimum file AGE - exclude files older than n days/date.`
So your code should be:
set "today=20180721"
robocopy "C:\temp\" "D:\backup\temp\" *.* /s /DCOPY:T /MAXAGE:%today%
Going to assume you thought the options were for INCLUDE.
robocopy's /MINAGE//MAXAGE options regard the full date and time, so specifying something like /MAXAGE:1 filters for files that have been modified within the last 24 hours.
If you want to process files which have been modified today only, hence regarding the date but not the time, you could use forfiles and its '/D' option, like this:
set "DEST=D:\backup\temp"
forfiles /P "C:\temp" /D +0 /C "cmd /C if #isdir==FALSE for %%Z in (#relpath) do #(2> nul md 0x22%DEST%\%%~Z\..0x22 & copy #relpath 0x22%DEST%\%%~Z0x22)"

Delete multiple directories with a single batch file

I would like to make a batch script that can delete multiple directories at once. I've searched the web, but only seem to find methods for deleting multiple sub-directories or files. So far I can make a script to delete one specific folder using this structure:
rmdir "C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Cookies" /S /Q
I then tried a multitude of methods to declare other folders in different combinations and sequences but none seem to work. First I tried putting all other directories in a single line followed by /S /Q, then placing rmdir and /S /Q at the start and end of each new path, then putting each path on a new line by pressing enter. Am I using the wrong commands? Any help is appreciated.
for %%a in ("dirname 1" "dirname2" "as many as you want") do rd /s /q "%%~a"
should do what you want - %%a is set to each [optionally-quoted] argument in turn. You Must use the quotes if the directoryname contains separators like spaces.
You can just use a for loop to iterate over a list of directories, as per:
pax> for %d in (c:\dir1 c:\other\dir2) do echo %d
c:\dir1
c:\other\dir2
In your particular case, it would be something akin to (in a cmd file):
for %%d in (c:\dir1 c:\other\dir2) do rmdir "%%~d" /s /q
You can find subdirectories by name automaticly and delete them
for /f %%d in ('dir /b "C:\exampledir\searched_dir_name*"') do rd /s /q "C:\exampledir\%%d"
this command will delete all directories with name "searched_dir_name" in directory C:\exampledir\

Batch file to rename folders with wildcard or create a new folder and move contents?

I'm trying to tidy up a data folder and have written a batch file to take care of a lot of preliminary work (delete empty folders, delete junk files, etc), but I'm falling over when trying to deal with files within duplicate folders.
This is an example of the current situation:
w:\Data\Corporations\555\20130101\Concat_000001\555_20130101_data.zip
w:\Data\Corporations\555\20130101\Concat_000002\555_20130101_data.zip
w:\Data\Corporations\555\20130101\Concat_000003\555_20130101_data.zip
w:\Data\Corporations\555\20130101\Concat_000004\555_20130101_data.zip
There should only be one Concat folder per YYYYMMDD folder, and should look like this:
w:\Data\Corporations\555\20130101\Concat\555_20130101_data.zip
There are hundreds of folders in w:\Data\Corporations to be processed, so I figure I need to first of all find any folder named Concat_*, make a folder named Concat within the same parent folder, and then move any zip from Concat_ to Concat.
I have tried various combinations of FOR /D in (Concat_*) with MD and MOVE commands, but with no luck so far. I've also tried calling a subroutine from the FOR statement that would jump back a level in the tree, create a folder named Concat, go back to Concat_* and move the .zip files, but again with no luck.
Any help would be greatly appreciated.
Cheers,
Pete
try this:
for /r "w:\Data\Corporations\555" %%a in (*.zip) do for %%b in ("%%~dpa.") do md "%%~dpbConcat" 2>nul & move /y "%%~fa" "%%~dpbConcat"
The following does what you asked. If you uncomment the last line, then empty config_* folders will be removed. Non-empty config_* folders will be preserved.
#echo off
for /f "delims=" %%F in ('dir /b /ad /s concat_*') do (
if not exist "%%~dpFconcat\" mkdir "%%~dpFconcat\"
if exist "%%F\*.zip" move /y "%%F\*.zip" "%%~dpFconcat\" >nul
REM uncomment line below if you want to remove empty concat_* folders
REM dir /b "%%F"|findstr "^" >nul || rd "%%F"
)

adding dates to copied files

I am trying to add the dates to copied files from one directory to another directory. This is how it should look like
Original file name: XEsalary.csv
Result file name: XEsalary-2013-02-15.csv
Here is my code:
set REMOTE=U:\
set LOG=C:\Integration\FE\log_test
set PVM=%DATE:~9,4%-%DATE:~6,2%-%DATE:~3,2%
set YY=%DATE:~9,4%
set LOCAL=C:\FTP\VC\test
cd %LOCAL%
xcopy /y /f /v "%LOCAL%\*.csv" "%REMOTE%\" >>%LOG%\%PVM%.log
xcopy /y /f /v "%LOCAL%\*.csv" "%LOCAL%\archive\*.csv"
:: assist with turning this into a for loop
ren %LOCAL%\archive\*.csv %LOCAL%\archive\*%PVM%.csv
echo. >>%LOG%\%PVM%.log
copying works just file. It is the renaming part which is not working. Any help please?
Thx in advance :-)
Using wildcards with RENAME is tricky. There is no good official documentation, but I have experimented and published rules as to how it works: See How does the Windows RENAME command interpret wildcards?
You can accomplish your rename with the following command, as long as none of your file names include dots (the last extension dot is OK).
ren "%LOCAL%\archive\*.csv" ????????????????????-%PVM%*
The number of ? must be greater than or equal to the longest name in the folder.
The result will be incorrect if a file name contains a dot. For example, part1.part2.csv would become part1-2013-02-15.part2.csv.
Another option is to use a FOR loop. You can safely append the date to any file using this technique.
for %%F in ("%LOCAL%\archive\*.csv") do ren "%%F" "%%~nF-%PVM%%%~xF"
BUT, both solutions have a problem if you rerun the process on a later date. New files will be added to the archive, but both new and old archive files will be renamed to the current date. That won't work.
Better to copy and rename the file in one step using a FOR loop as suggested in rojo's answer.
Or better yet, create a new archive folder with the date in the folder name, and then copy the files to the dated archive folder without renaming :-)
set REMOTE=U:\
set LOG=C:\Integration\FE\log_test
set PVM=%DATE:~9,4%-%DATE:~6,2%-%DATE:~3,2%
set YY=%DATE:~9,4%
set LOCAL=C:\FTP\VC\test
cd %LOCAL%
xcopy /y /f /v "%LOCAL%\*.csv" "%REMOTE%\" >>%LOG%\%PVM%.log
md "%LOCAL%\archive\%PMV%
xcopy /y /f /v "%LOCAL%\*.csv" "%LOCAL%\archive\%PVM%"
You might want to include the time in the folder name if the process could be run multiple times in the same day.
Windows doesn't let you rename with a wildcard. You have to name each file in a for loop. Might as well do the renaming as you're copying. Does this do what you intended?
#echo off
setlocal
set REMOTE=U:\
set LOG=C:\Integration\FE\log_test
set PVM=%DATE:~9,4%-%DATE:~6,2%-%DATE:~3,2%
set YY=%DATE:~9,4%
set LOCAL=C:\FTP\VC\test
xcopy /y /f /v "%LOCAL%\*.csv" "%REMOTE%\" >>%LOG%\%PVM%.log
pushd "%LOCAL%"
for %%I in (*.csv) do (
rem Uncomment the following line to log the copy to archive.
rem echo copy "%%I" -^> "%LOCAL%\archive\%%~nI-%PVM%.csv" >>%LOG%\%PVM%.log
copy "%%I" "%LOCAL%\archive\%%~nI-%PVM%.csv">NUL
)
echo. >>%LOG%\%PVM%.log
popd

Resources