I'm messing around with dos and batch files for the first time and I am trying to make a "program" to backup my Minecraft saves (lol). I want the program to rename the current save (in my MinecraftSaves folder) as "Backup#" before the next one is copied into the MinecraftSaves folder. Its simple enough to rename it, but I want it to save multiple folders, each incrementing a number at the end of the folder name (ie Backup1, Backup2, Backup3). Any help? I've looked all over but I couldn't find something exactly to fit my needs.
#Echo off
title Minecraft Backup
echo.
echo.
echo.
echo Do you want to backup you're Single Player World?
echo.
SET /P ANSWER=Do you want to continue (Y/N)?
if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={yes} (goto :yes)
if /i {%ANSWER%}=={n} (goto :no)
if /i {%ANSWER%}=={no} (goto :no)
:no
PING 1.1.1.1 -n 1 -w 1000 >NUL
exit
:yes
ren C:\Users\Josh\Desktop\MinecraftSaves\SinglePlayer Backup
xcopy C:\Users\Josh\AppData\Roaming\.minecraft\saves C:\Users\Josh\Desktop\MinecraftSaves /-y /e /h
Thats what I have so far. I want to change the following to rename the SinglePlayer folder as backup1, and the next time I run it have it rename the new SinglePlayer folder as backup2. I'm trying to explain this as best I can. Maybe theres a simpler way to do this. I just need it to make backups with numbers on the backup folders. Hope thats clear enough.
Excuse me. I think I did not really understood your question. However, the following Batch file take an existent folder named CurrentSave and rename it to Backup-# adding 1 to the last Backup-# existent folder. The dash in the folder name make things easier.
#echo off
for /D %%d in (Backup-*) do set lastfolder=%%d
for /F "tokens=2 delims=-" %%n in ("%lastfolder%") do set /A nextnumber=%%n+1
move CurrentSave Backup-%nextnumber%
If this is not what you want, give us more details so we may help you.
EDIT
OK. The code I posted above works right, just a couple details are needed. Below is the code you must insert from :yes label on:
:yes
set lastfolder=Backup-0
for /D %%d in (C:\Users\Josh\Desktop\MinecraftSaves\Backup-*) do set lastfolder=%%~Nd
for /F "tokens=2 delims=-" %%n in ("%lastfolder%") do set /A nextnumber=%%n+1
ren C:\Users\Josh\Desktop\MinecraftSaves\SinglePlayer Backup-%nextnumber%
xcopy C:\Users\Josh\AppData\Roaming\.minecraft\saves C:\Users\Josh\Desktop\MinecraftSaves /-y /e /h
May I suggest you another modification?
SET /P ANSWER=Do you want to continue (Y/N)?
for %%a in (y yes) do if /i "%ANSWER%"=="%%a" goto yes
:no
Please let me know if you solved your problem.
Related
First post here :) I am new to creating batch files and have created the below batch file (which took me about 3 weeks to figure out, LOL). Basically, when we get a new assignment we copy the template folder and then rename it the next unused folder name, eg. if the last folder was 15-P0028 the next one would be 15-P0029. the batch works perfectly! But, sometimes we want to add a client name to the end of the folder name, eg. 15-P0029 Brown. I want the batch to pause for user input after renaming the folder the next in sequence so we can enter a client name or just hit enter to insert the new folder without the client name. I think using the set /p would work but I have no idea how to use it properly.
Can anyone help me with this, it would be greatly appreciated.
#echo off
setlocal enableDelayedExpansion
cd /d C:\Users\jbrown\Desktop\Test
set I=2
:NextI
if /I %I% LEQ 999 set II=0%I%
if /I %I% LEQ 99 set II=00%I%
if /I %I% LEQ 9 set II=000%I%
if not exist "15-P!II!" (
xcopy /s /e /i "15-P0000-Template" "15-P!II!"
goto :eof
)
set /a I+=1
if /i %I% LSS 9999 goto NextI
)
yep, you got it, you need the /p "prompt" command. Something like this would work
if not exist "15-P!II!" (
set /p "client_name=OPTIONAL Enter a client name and press <ENTER>: "
xcopy /s /e /i "15-P0000-Template" "15-P!II!!client_name!"
goto :eof
)
we don't need to do any extra processing to check if the user entered a value. If they simply pressed enter client_name should just be an empty string. so adding an empty string onto the end won't affect the name
Im trying to copy files from one drive to another using a batch file, Which works! but we keep Changing file names on our main file which creates addition copys with diffrent names everytime its run. I dont want to delete the Copy file entirely bacause of the length of time the copy takes just to copy. I would like to Compare the 2 files and delete the files that are no longer on the main drive here is the test that im working on. Thanks for any help you can give me.
#echo
cls
If not exist "C:\Users\Jeremy\Desktop\Test Main\*.*" "Del "C:\Users\Jeremy\Desktop\Test Clone\*.*"
xcopy "C:\Users\Jeremy\Desktop\Test Main\*.*" "C:\Users\Jeremy\Desktop\Test Clone\*.*" /D /C /E /S /I /Y /V /H /R /F /d:01-01-1998
pause
:abort
echo You pressed CTRL+C to end the copy operation.
goto exit
you might want to look into robocopy, specifically with the /mir switch, which mirrors (copy all new files and delete all no longer existing files) the source folder to the target.
Thanks
This does work
#echo
cls
robocopy /MIR "C:\Users\Jeremy\Desktop\Test Main" "C:\Users\Jeremy\Desktop\Test Clone"
pause
:abort
echo You pressed CTRL+C to end the copy operation.
goto exit
But I would still like to understand if anyone can or wants to take the time to correct my original question
Try:
#echo off
cls
If not exist "C:\Users\Jeremy\Desktop\Test Main\*.*" "Del "C:\Users\Jeremy\Desktop\Test Clone\*.*"
xcopy "C:\Users\Jeremy\Desktop\Test Main\*.*" "C:\Users\Jeremy\Desktop\Test Clone\*.*" /D /C /E /S /I /Y /V /H /R /F /d:01-01-1998
If %errorlevel% EQU 2 (
echo You pressed CTRL+C to end the copy operation.
)
pause
My working batch file scans a long list of remote servers, copies anything there to a local server, checks the log file for a keyword, and if the keyword is found sends an email. I noticed it is always sending emails, even with a blank log file.
I discovered both FOR loops are using the %1 variable for their output - as seen in ECHO %1 and each line of the called :servermove. For lack of a better explanation it is not resetting %1 to null between loops.
I reviewed almost a dozen SO posts and am somewhat confident using SETLOCAL ENABLEDELAYEDEXPANSION would resolve this. That is where my understanding ends and I am unsuccessful thus far.
Here is the relevant code:
SET DATE=%date:~4,2%-%date:~7,2%-%date:~10,4%
SET HH=%time:~0,2%
SET MN=%time:~3,2%
SET TSTAMP=Time Run is %HH%%MN%
SET DATETIME=%DATE% at %HH%%MN%
SET LOGFILE="\\nt980a3\CreditFileImagesTransmission\LogFiles\%DATETIME%-File Move Log.txt"
SET MailDst=
SET MailSrc=
SET MailSrcName=Center to LDSD File Mover
SET OKMailSub=A Branch Has Sent You Some Files
ECHO %DATETIME% > %LOGFILE%
ECHO. >> %LOGFILE%
FOR /F "tokens=1" %%A IN (%~dp0SourceServers.txt) DO CALL :ServerMove %%A
:cleanuplogs
PUSHD "\\nt980a3\CreditFileImagesTransmission\LogFiles" &&(
FORFILES /S /M *.txt /D -45 /C "CMD /C DEL /Q #path"
) & POPD
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
:successmail
IF EXIST %temp%\to.txt DEL %temp%\to.txt
FOR %%a IN (%MailDst%) DO ECHO %%a>>%temp%\to.txt
"%~dp0sendmail.exe" /TO=%temp%\to.txt /FROM=%MailSrcName% ^<%MailSrc%^> /REF=%OKMailSub% /MESSAGE=%LOGFILE% /HOST=
:exit
EXIT
:ServerMove
DIR /S /B \\%1\CreditFileImagesTransmission\*.* >> %LOGFILE%
XCOPY /E /C /I /Y "\\%1\CreditFileImagesTransmission\*.*" "\\nt980a3\CreditFileImagesTransmission\%DATE%\%HH%%MN%\"
FOR /D %%P IN ("\\%1\CreditFileImagesTransmission\*.*") DO RMDIR "%%P" /Q /S
DEL /Q /S "\\%1\CreditFileImagesTransmission\*.*"
I tried changing :mailtest to use %%B in both instances but that also fails. Placing SETLOCAL ENABLEDELAYEDEXPANSION and its counterpart ENDLOCAL before one or the other loop and changing the %%A to !A! does not work either.
Would someone kindly point out the error in my ways and offer suggestions or resources that will help me resolve this?
%1 is the first parameter provided to the procedure - either from the command-line (in the main procedure) or the parameter following the procedure name in call :procedurename parameter1.
In your case, %1 to :servermove is an entry from SourceServers.txt and %1 to :searchlog is each line from %LOGFILE%.
Since you've censored your batch, what you've posted makes little sense. For instance, the :searchlogs routine will take the first line from %LOGFILE% and go to successmail or cleanlogs depending on whether that first line contains the target string \\nt. What it does from there, we can't tell.
We're faced with an XY problem - trying to fix a solution, not a problem.
First problem: Don't use date as a user-variable. It's a "magic variable" which contains the date but it's overridden by a specific set statement.
Having run :servermove for each entry in SourceServers.txt, you are
- accumulating a directory list from \CreditFileImagesTransmission\*.* on that server.
- copying those files to server nt980a3 with a date/timestamp but not including the source-servername so any duplicate name anywhere will overwrite an earlier version. I suggest you include %1 into your destination-name.
- deleting subdirectories
- deleting files.
I'd suggest you simply remove the directory \\%1\CreditFileImagesTransmission\, then re-create it.
I'd also suggest that you add an extra line
goto :eof
after the del /q /s... line. This will cause execution to be transferred to the end-of-file (the colon in :eof is required) and may seem superfluous, but it ensures that the routine has a defined endpoint - if you add a further routine, there is no way the :servermove routine will continue into your new code.
After each server has been processed, you proceed to the :cleanuplogs routine, which I presume deletes logs older than 45 days.
Your next statement is a real problem. What it will do is grab the very first line of the logfile (which contains "%DATE% at %HH%%MN%" with the date resolved as you've set at the start and it then processes this line in :searchlog; there is no \\nt in this line, so errorlevel is set to 1, and the batch proceeds to :EXIT (not a good label in my view, since it's a keyword); executes an exitand should terminate the batch.
This appears not to be what it is actually doing, and I'm at a loss to explain why.
I'd suggest changing
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
to
:mailtest
find "\\nt" %LOGFILE%>NUL
IF NOT ERRORLEVEL 1 GOTO successmail
:failmail
echo "\\nt" was found in the log
pause
GOTO exit
but I can't test that...
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
You are missing a GOTO :EOF or similar goto here because it will drop through to the routine below once the above is finished.
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
I feel you can not carry the %1 of first for loop to others. Try to transfer that to another variable like below.
:ServerMove
set servername=%1
DIR /S /B \\%servername%\CreditFileImagesTransmission\*.* >> %LOGFILE%
XCOPY /E /C /I /Y "\\%servername%\CreditFileImagesTransmission\*.*" "\\nt980a3\CreditFileImagesTransmission\%DATE%\%HH%%MN%\"
FOR /D %%P IN ("\\%servername%\CreditFileImagesTransmission\*.*") DO RMDIR "%%P" /Q /S
DEL /Q /S "\\%servername%\CreditFileImagesTransmission\*.*"
Cheers, G
I need to delete all .jpg and .txt files (for example) in dir1 and dir2.
What I tried was:
#echo off
FOR %%p IN (C:\testFolder D:\testFolder) DO FOR %%t IN (*.jpg *.txt) DO del /s %%p\%%t
In some directories it worked; in others it didn't.
For example, this didn't do anything:
#echo off
FOR %%p IN (C:\Users\vexe\Pictures\sample) DO FOR %%t IN (*.jpg) DO del /s %%p\%%t
What I'm I missing in the second snippet? Why didn't it work?
You can use wildcards with the del command, and /S to do it recursively.
del /S *.jpg
Addendum
#BmyGuest asked why a downvoted answer (del /s c:\*.blaawbg) was any different than my answer.
There's a huge difference between running del /S *.jpg and del /S C:\*.jpg. The first command is executed from the current location, whereas the second is executed on the whole drive.
In the scenario where you delete jpg files using the second command, some applications might stop working, and you'll end up losing all your family pictures. This is utterly annoying, but your computer will still be able to run.
However, if you are working on some project, and want to delete all your dll files in myProject\dll, and run the following batch file:
#echo off
REM This short script will only remove dlls from my project... or will it?
cd \myProject\dll
del /S /Q C:\*.dll
Then you end up removing all dll files form your C:\ drive. All of your applications stop working, your computer becomes useless, and at the next reboot you are teleported in the fourth dimension where you will be stuck for eternity.
The lesson here is not to run such command directly at the root of a drive (or in any other location that might be dangerous, such as %windir%) if you can avoid it. Always run them as locally as possible.
Addendum 2
The wildcard method will try to match all file names, in their 8.3 format, and their "long name" format. For example, *.dll will match project.dll and project.dllold, which can be surprising. See this answer on SU for more detailed information.
You can use this to delete ALL Files Inside a Folder and Subfolders:
DEL "C:\Folder\*.*" /S /Q
Or use this to Delete Certain File Types Only:
DEL "C:\Folder\*.mp4" /S /Q
DEL "C:\Folder\*.dat" /S /Q
I wrote a batch script a while ago that allows you to pick a file extension to delete. The script will look in the folder it is in and all subfolders for any file with that extension and delete it.
#ECHO OFF
CLS
SET found=0
ECHO Enter the file extension you want to delete...
SET /p ext="> "
IF EXIST *.%ext% ( rem Check if there are any in the current folder :)
DEL *.%ext%
SET found=1
)
FOR /D /R %%G IN ("*") DO ( rem Iterate through all subfolders
IF EXIST %%G CD %%G
IF EXIST *.%ext% (
DEL *.%ext%
SET found=1
)
)
IF %found%==1 (
ECHO.
ECHO Deleted all .%ext% files.
ECHO.
) ELSE (
ECHO.
ECHO There were no .%ext% files.
ECHO Nothing has been deleted.
ECHO.
)
PAUSE
EXIT
Hope this comes in useful to anyone who wants it :)
I don't have enough reputation to add comment, so I posted this as an answer.
But for original issue with this command:
#echo off
FOR %%p IN (C:\Users\vexe\Pictures\sample) DO FOR %%t IN (*.jpg) DO del /s %%p\%%t
The first For is lacking recursive syntax, it should be:
#echo off
FOR /R %%p IN (C:\Users\vexe\Pictures\sample) DO FOR %%t IN (*.jpg) DO del /s %%p\%%t
You can just do:
FOR %%p IN (C:\Users\0300092544\Downloads\Ces_Sce_600) DO #ECHO %%p
to show the actual output.
this is it:
#echo off
:: del_ext
call :del_ext "*.txt"
call :del_ext "*.png"
call :del_ext "*.jpg"
:: funcion del_ext
#echo off
pause
goto:eof
:del_ext
set del_ext=%1
del /f /q "folder_path\%del_ext%"
goto:eof
pd: replace folder_path with your folder
Step 1:
Navigate to the folder in question using the cd command
For example:
cd C:\Users\tremanleo\Desktop\HoldLEOCMS
Step 2
Delete the the file type.
For Example:
DEL *.bak
If you are trying to delete certain .extensions in the C: drive use this cmd:
del /s c:\*.blaawbg
I had a customer that got a encryption virus and i needed to find all junk files and delete them.
I would like to lock a series of file from my staff so they can not delete them i have thus compiled a script wich puts the CACLS function into a loop. however this is not taking effect.
could somebody please explain why?
FOR /F %%i IN (c:\file.txt) DO CACLS %%i /p :n /y
I have been able to narrow it down to the /y at the end how can i continue to Automate the yes?
There are a couple of things wrong.
Firstly you haven't specified a user/group that you want to apply the permissions to
Example
CACLS %%i /p Everyone:n /y
Secondly, there is no /y switch for cacls. If you want to automatically say y to the confirmation you can use this
echo y| CACLS %%i /p Everyone:n /y
So your full batch file would look similar to this
FOR /F %%i IN (c:\file.txt) DO echo y| CACLS %%i /p Everyone:n
Hope this helps