How it should work/What it should do:
At C:\Users\RandomUser/Game I want to replace the file at C:\Users\RandomUser/Game/ConsoleVariables.ini.
In order to do so the user should prepare a folder with his different ini files and that path will be hardcoded in the .bat script.
After running the script it will count how many .ini files were found in the hardcoded path (works) and display them in cmd with a number from 1 to n behind the files so the user sees what number to press to choose the according file. CMD-Screenshot
If the user enters a number (validation check would be nice) the original .ini file at the game location should be deleted and be replaced by the .ini file which he chose and the copied ini file should be renamed to ConsoleVariables.ini (the file will be copied so it won't disappear in the folder so it can be re done).
What I have working:
1) loop through all ini files and display them with the number from 1 to n behind them
2) I know how to copy/paste files
What's missing:
1) Get userinput(number) and copy the according file depending on the input(Not sure how to loop/map the userinput to the actual ini files so 1 is actually bound to the first .ini file and so on)
2) rename copied file to ConsoleVariables.ini but don't change the name from the original file
#echo off
set iniFolder=C:\Users\RandomUser\Inis
set iniDestinationFolder=C:\Users\RandomUser/Game
setlocal enableextensions
setlocal ENABLEDELAYEDEXPANSION
set count = 0
set /a c=0
FOR %%i in (%iniFolder%\*.txt) DO set /a count+=1 & set /a c=c+1 & echo %%i !c!
echo *****%count% ini files found*****
echo press the according number to replace your ini file (1 - %count%)
endlocal
::logic missing here
set /P id=Enter number:
If id==1 goto accepted
:accepted
del %iniDestinationFolder%\Test.txt
xcopy %iniFolder%\Test2.txt %iniDestinationFolder%
pause
Note: In the example above im using .txt files instead of .ini files for testing purposes.
Any help is appreciated!
You can do it easily by using an array like this code below :
#echo off
set "iniFolder=%userprofile%\Desktop\Inis"
set "iniDestinationFolder=%userprofile%\Desktop\Game"
setlocal ENABLEDELAYEDEXPANSION
set count=0
REM Just replace the variable "Ext=txt" by "Ext=ini" after testing it with text files !
Set "Ext=txt"
echo(
REM In this loop (FOR .. DO) ==> We fill the list files into an array
FOR %%f in ("%iniFolder%\*.%Ext%") DO (
SET /a "Count+=1"
set "list[!Count!]=%%~nxf"
set "listpath[!Count!]=%%~dpFf"
)
REM In this loop (FOR..DO) ==> Display array elements in order to show the list files found
For /L %%i in (1,1,%Count%) Do (
echo %%i-!list[%%i]!
)
echo(
echo *****%count% %Ext% files found*****
Set /a "First=%count%-%count% + 1"
echo press the according number to replace your %Ext% file (%First% - %count%)
Set /p "Input="
For /L %%i in (1,1,%Count%) Do (
If [%INPUT%]==[%%i] (
xcopy /I /F "!listpath[%%i]!" "%iniDestinationFolder%\"
)
)
pause & exit
Assuming you have less than 10 ini files in the directory, we can use choice instead:
#echo off
set "iniFolder=%userprofile%\Inis"
set "iniDestinationFolder=%userprofile%\Game"
setlocal enabledelayedexpansion
set cnt=0
for %%i in ("%inifolder%\*.txt") DO (
set /a cnt+=1
set "file!cnt!=%%~nxi"
set chc=!chc!!cnt!
call echo !cnt!. %%file!cnt!%%
)
choice /c !chc! /m "Select a file"
copy /Y "%iniFolder%\!file%errorlevel%!" "%iniDestinationFolder%\ConsoleVariables.ini"
Related
I've got quite a lot of files I am trying to archive for the company I work for. I am a little familiar with Batch scripts, but I do not quite understand enough to fully get what I am after.
I am trying to copy some files based on the beginning of their file name into folders on our NAS. The files are 7z files and their structure is going to be like so:
5476 BMW Handle-A.7z
5487 Chevy-Imp.7z
5986 Honda Lid-Upper.7z
etc.
The file structure works like this: the four numbers at the beginning is our company job number. On our NAS we have an archive directory with folders in it like this:
_5000-5999
_6000-6999
And inside of those folders are folders that will contain 250 archive files each. They are formatted like this:
_5000-5249
_5250-5499
_5500-5749
_5750-5999
I am looking to create a Batch file that I can drag these 7z files onto and it will read the first four numbers of the file name, and copy it to the proper folder on our NAS.
So for instance the files:
5476 BMW Handle-A.7z
5487 Chevy-Imp.7z
Would copy into
\nas01\archive\ _5000-5999\ _5250-5499
etc.
The main code I was messing with was this:
#echo off
for /f "delims=" %%i in ('dir /b /a-d *.7z') do (
set "filename1=%%~i"
setlocal enabledelayedexpansion
set "folder1=!filename1:~0,4!"
mkdir "!folder1!" 2>nul
copy "!filename1!" "!folder1!" >nul
)
What is not working for me is this line:
set "folder1=!filename1:~0,4!"
How can I create some sort of variable to check the file name, create the folders if necessary and copy it to the correct folder? I would appreciate any help on this!
-Dustin
Thanks to some help from commenters, I was able to figure it out. I was having a problem with how to structure the script, but I got it!
#echo off
for /f "delims=" %%i in ('dir /b /a-d *.7z') do (
set "filename=%%~i"
setlocal enabledelayedexpansion
set "folder1=!filename:~0,4!"
set "subfolder1=_!folder1:~0,1!000-!folder1:~0,1!999"
set "firstdigit=!filename:~0,1!"
set "parent=\\nas01\The_Archives"
REM CONDITIONAL STATEMENTS
IF !folder1! GEQ !firstdigit!000 IF !folder1! LEQ !firstdigit!249 SET "subfolder2=_!firstdigit!000-!firstdigit!249"
IF !folder1! GEQ !firstdigit!250 IF !folder1! LEQ !firstdigit!499 SET "subfolder2=_!firstdigit!250-!firstdigit!499"
IF !folder1! GEQ !firstdigit!500 IF !folder1! LEQ !firstdigit!749 SET "subfolder2=_!firstdigit!500-!firstdigit!749"
IF !folder1! GEQ !firstdigit!750 IF !folder1! LEQ !firstdigit!999 SET "subfolder2=_!firstdigit!750-!firstdigit!999"
mkdir "!parent!\!subfolder1!\!subfolder2!" 2>nul
copy "!filename!" "!parent!\!subfolder1!\!subfolder2!" >nul
)
I learned more about Batch today, so it was a day well spent!
Is there a way I can make this to where you just click and drag the files into this Batch script instead of grabbing all of the 7z files in the folder?
Here is a complete batch code for this task using mainly arithmetic expressions and string concatenations to determine the target folder path for each *.7z file in source folder, or alternatively for each file of which name is passed via an argument to the batch file.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Source path is the directory of the batch file ending with a backslash.
set "SourcePath=%~dp0"
rem Target path is a UNC path also ending with a backslash.
set "TargetPath=\\nas01\archive\"
rem Run subroutine ProcessFile for each *.7z file in source folder
rem if not at least 1 file was specified on command line to process.
rem Otherwise process the files of which names are passed as arguments
rem to this batch file on starting it.
if "%~1" == "" (
for %%I in ("%SourcePath%*.7z") do call :ProcessFile "%%I"
) else (
for %%I in (%*) do call :ProcessFile "%%~I"
)
rem Restore previous environment and exit this batch file.
endlocal
goto :EOF
rem The subroutine ProcessFile determines the target folders based on
rem first part of the file name separated with one or more spaces from
rem rest of the file name which should be a positive integer number.
rem File names not starting with a valid number are copied (or moved)
rem to the folder _0000-0249\_0000-0249 in specified target folder.
rem For file numbers less than 1000 an extra code is added to copy (or move)
rem those files into folders also having at least 4 digit numbers in name.
:ProcessFile
for /F %%J in ("%~n1") do set "FileNumber=%%J"
set /A FolderNumber1=(FileNumber / 1000) * 1000
set /A FolderNumber2=FolderNumber1 + 999
set /A FolderNumber3=FileNumber - FolderNumber1
if %FolderNumber3% LSS 250 (
set "FolderNumber3=%FolderNumber1%"
set /A FolderNumber4=FolderNumber1 + 249
goto BuildFolderPath
)
if %FolderNumber3% LSS 500 (
set /A FolderNumber3=FolderNumber1 + 250
set /A FolderNumber4=FolderNumber1 + 499
goto BuildFolderPath
)
if %FolderNumber3% LSS 750 (
set /A FolderNumber3=FolderNumber1 + 500
set /A FolderNumber4=FolderNumber1 + 749
goto BuildFolderPath
)
set /A FolderNumber3=FolderNumber1 + 750
set "FolderNumber4=%FolderNumber2%"
:BuildFolderPath
if %FolderNumber1% == 0 (
set "FolderNumber1=0000"
set "FolderNumber2=0%FolderNumber2%"
set "FolderNumber4=0%FolderNumber4%"
if %FolderNumber3% == 0 (
set "FolderNumber3=0000"
) else (
set "FolderNumber3=0%FolderNumber3%"
)
)
set "TargetFolder=%TargetPath%_%FolderNumber1%-%FolderNumber2%\_%FolderNumber3%-%FolderNumber4%"
mkdir "%TargetFolder%" 2>nul
copy /Y "%~1" "%TargetFolder%\" >nul
rem move /Y "%~1" "%TargetFolder%\" >nul
goto :EOF
A subroutine is used instead of doing everything within FOR loop as this makes the task much easier to code because of GOTO can be used in the subroutine. And with a subroutine it is not necessary to use delayed environment variable expansion which is helpful in case of a *.7z file ever contains an exclamation mark.
The main advantage of this solution: it works with numbers in range 0 to 2147482999 in file name.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
copy /?
echo /?
endlocal /?
for /?
goto /?
if /?
mkdir /?
move /?
rem /?
setlocal /?
Read also the Microsoft article about Using Command Redirection Operators explaining >nul and 2>nul used to redirect success and error messages to device NUL to suppress them.
I have a folder that has bmp files , they may be 4 in a folder or 50 in a folder, but they are
image.bmp
image1.bmp
image2.bmp
I started a batch file with the below code:
#echo off
setlocal enableDelayedExpansion
SET counter=0
SET /P filename=Please enter the filename:
for %%G in (C:\Test_Folder) do (
ren image*.bmp "%filename%""%counter%".bmp
SET /A counter=%counter%+1;
echo "%counter%"
)
pause
but the counter does not increment, can some one give some light to my code?
#echo off
setlocal enableDelayedExpansion
SET counter=0
SET /P filename=Please enter the filename:
for %%G in (C:\Test_Folder\image*.bmp) do (
ren "%%~G" "%filename%!counter!.bmp"
SET /A counter+=1
echo "!counter!"
)
pause
Changes:
using delayed expansion for the counter variable.
forprocesses matching files in the folder instead of the folder itself.
use ren to rename single files instead of wildcard usage.
SET /A counter+=1 instead of SET /A counter=!counter!+1 (does the same, but improved readabilty).
I am trying to create a windows batch file that will:
1st: List files in current directory and output to a filenamelist (Filelist_[YYY][MM][DD][hh][mm]ss])
2nd: From the given filenamelist, read each line as an input for 3rd step
3rd: Read the first line of the file and extract 7th, 9th, and and 14th string.
Delimiter can be "~", "*" and "^"
4th: Assign 7th as ISAsender variable, 9th as ISAreceiver, and 14th string as ISActrlnum.
5th: Redirect the echoed variables to a single logfile (EDI.log).
EDIT:
6th: Check ISAsender's CNtable.txt (Ex. AP_CNtable.txt for ISA's APPLESND, SS_CNtable for SAMSUNGSND) if ISActrlnum already exists or duplicate. Initially CNtable.txt contains dumped values of ISActrlnum (control numbers).
a. If there is duplicate control number found, exit with error message and output to Dupfile.txt as well as the ISActrlnum in issue. Move file to EXCEPT folder.
b. If not duplicate, insert ISActrlnum to CNtable.txt then proceed to 7th.
7th: Use IF condition for ISAsender and ISAreceiver to move the file to a correspoinding folder.
8th: Repeat 3rd-7th until 2nd step reaches EOF or finished reading each lines.
Example: From a given Filelist_20141022010101, FileName.txt contains the following having "~" as delimiter:
ISA~00~ ~00~ ~ZZ~APPLESND ~14~APPLERCV ~130214~2300~U~00401~000000001~0~T~>
GS~FA~APPLESND~APPLERCV~20130214~2300~810~X~004010
ST~997~131250001
AK1~SC~1809
AK9~A~1~1~1
SE~4~131250001
GE~1~810
IEA~1~000000001
while CNtable.txt contains:
000000004
000000002
000000003
000000005
Since ISActrlnum=000000001 does not exist in CNtable.txt, it will update CNtable.txt by appending ISActrlnum. Here only conditional statements for the ISAsender and ISAreceiver will be utilized.
So if ISAsender=APPLESND and ISAreceiver=APPLERCV move the curent file (FileName.txt) to specific directory such as C:\VP\APPLE.
Same logic for the next filename inside Filelist_20141022010101.
I was able to write code below but don't know how to get the filename from FORFILES and use it again as variable input in the FOR LOOP.
REM FileReceiver.bat
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set TIMESTAMP=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
C:
cd "C:\VP"
FORFILES /P "C:\VP" >"FLIST.%TIMESTAMP%"
set first=1
for /f "tokens=7 delims=~" %%a in (FileName.txt) do (
if %first%==1 (
set first=0
set ISAsender=%%a
echo %ISAsender%
)
)
set first=1
for /f "tokens=9 delims=~" %%b in (FileName.txt) do (
if %first%==1 (
set first=0
set ISAreceiver=%%b
echo %ISAreceiver%
)
)
set first=1
for /f "tokens=14 delims=~" %%c in (FileName.txt) do (
if %first%==1 (
set first=0
set ISActrlnum=%%c
echo %ISActrlnum%
)
)
if %ISAsender%=="APPLESND" if %ISAreceiver=="APPLERCV" (
move FileName.txt "C:\VP\APPLE"
)
if %ISAsender%=="SAMSUNGSND" if %ISAreceiver=="SAMSUNGRCV" (
move FileName.txt "C:\VP\SAMSUNG"
)
Can anyone help me to satisfy the requirement without having to call another batch file that checks the duplicate control numbers (ISActrlnum) ?
As much as possible I want the whole code in a single bat file. Please bear with my lengthy description.
I needed to setup the entire environment you have on your computer to recode your batch file, but I think I got it.
Read the comments - the lines starting with rem - to understand the batch file and adapt it to your environment if this necessary.
#echo off
REM FileReceiver.bat
setlocal
rem Get current date and time as local time independent on Windows region settings.
for /F "tokens=2 delims==." %%T in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "dt=%%T"
rem Reformat the date and time strong to wanted format.
set "YYYY=%dt:~0,4%"
set "MM=%dt:~4,2%"
set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%"
set "Min=%dt:~10,2%"
set "Sec=%dt:~12,2%"
set "TimeStamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
rem Define name of the list file containing current date and time in name.
set "ListFile=FLIST_%TimeStamp%.lst"
rem Change directory (and drive).
cd /D "C:\VP"
rem Create the list file which is good here as the list of files changes
rem while running this batch file and therefore it is better to work with
rem a list file instead of running a FOR directly for each file in the
rem directory. The list file is not included in this list as it either does
rem not exist at all or it has wrong file extension as only *.txt files are
rem listed by command DIR. The log file EDI.log has also wrong file extension.
dir *.txt /A-D /B /ON >%ListFile%
rem It might be useful to delete the log file from a previous run.
if exist EDI.log del EDI.log
rem Process each file in the list file.
for /F "delims=" %%F in ( %ListFile% ) do call :ProcessFile "%%F"
rem Delete the list file as not needed anymore. It could be also kept.
del %ListFile%
rem Exit batch file.
endlocal
goto :EOF
:ProcessFile
rem The parameter passed from first FOR is the file name in double quotes.
set "FileName=%~1"
rem Ignore the files *_CNtable.txt and Dupfile.txt in same directory.
rem Command goto :EOF just exits here from subroutine ProcessFile.
if "%FileName%"=="AP_CNtable.txt" goto :EOF
if "%FileName%"=="SS_CNtable.txt" goto :EOF
if "%FileName%"=="Dupfile.txt" goto :EOF
rem Get 7th, 9th and 14th element from first line of current file.
for /f "usebackq tokens=7,9,14 delims=~*^" %%a in ( "%FileName%" ) do (
set "ISAsender=%%a"
set "ISAreceiver=%%b"
set "ISActrlnum=%%c"
goto WriteToLogFile
)
:WriteToLogFile
rem Remove all spaces as ISAsender and ISAreceiver have
rem usually spaces appended at end according to example
rem text. Then write file name and the 3 values to log file.
set "ISAsender=%ISAsender: =%"
set "ISAreceiver=%ISAreceiver: =%"
set "ISActrlnum=%ISActrlnum: =%"
echo %FileName%,%ISAsender%,%ISAreceiver%,%ISActrlnum%>>EDI.log
if "%ISAsender%"=="APPLESND" (
rem Check for ISA control number in file AP_CNtable.txt.
%SystemRoot%\System32\Findstr.exe /X /M /C:%ISActrlnum% AP_CNtable.txt >nul
if not errorlevel 1 goto Duplicate
echo %ISActrlnum%>>AP_CNtable.txt
if "%ISAreceiver%"=="APPLERCV" (
move /Y "%FileName%" "APPLE"
echo Moved %FileName% to directory APPLE.
)
)
if "%ISAsender%"=="SAMSUNGSND" (
rem Check for ISA control number in file SS_CNtable.txt.
%SystemRoot%\System32\Findstr.exe /X /M /C:%ISActrlnum% SS_CNtable.txt >nul
if not errorlevel 1 goto Duplicate
echo %ISActrlnum%>>SS_CNtable.txt
if "%ISAreceiver%"=="SAMSUNGRCV" (
move /Y "%FileName%" "SAMSUNG"
echo Moved %FileName% to directory SAMSUNG.
)
)
rem Exit the subroutine ProcessFile.
goto :EOF
:Duplicate
rem This ISA control number is already present in file *_CNtable.txt.
echo Duplicate control %ISActrlnum% found in file %FileName%.
echo %ISActrlnum%,%FileName%>>Dupfile.txt
rem Exit the subroutine ProcessFile.
goto :EOF
I'm not sure why the list file must have the current date and time in name, but perhaps you want to keep it for some unknown reason. In this case it would be necessary to delete 2 lines in code above - the line with command del %ListFile% and the comment line above.
Updated batch code on 2014-10-07 according to changes on point 6 in question.
I am trying to create a batch file to take photos off a camera or sd drive (which are specific and don't change.
I then want to move all the *.jpg to a different drive on the company's internal network.
The way it's set up it will look like n:\jobnumberfolder\pictures.jpg
I need the files to be able to be renamed like: "vpi(1).jpg", "vpi(2).jpg" and so on (the same thing you accomplish in Windows by highlighting multiple files and clicking rename.
The batch file will prompt the user for a job number (which will be the folder it will be moved to), and a description (what to name the file).
My programming experience is limited and in php and python, but I do understand the very basics: loops, if-else, arrays,... things like that.
My problem is that with the batch file, I cannot seem to find a good way to create a for loop to get what I want. I think I could do this in python using the os module, but I feel like I'm missing something simple (like a simple command or something I could be using for Windows).
I cannot even get a variable to increment, even with delayed expansion command. Even if I could, would it be possible to add it to the file name? I tried to find an answer for this, but have not been able to.
So my question are:
Can i actually do this in a batch file?
Would it be easier to just write a python script to do it, which will cause me to have to install python on the company's computer? I just want to be able to rename a file with a incrementing number at the end.
Something like this is what I'm looking for
i = 0
name = "whatever"
for each jpg in camera/images
rename each to whatever + i
i+=1
Any help would be appreciated.
Change n:\ in two places and f:\cam-folder\ where needed. It's untested:
#echo off
:loop
cls
echo Enter "jobnumberfolder,description" with comma and no quotes:
echo similar to 986,vpi
set "var="
set /p "var="
for /f "tokens=1,* delims=," %%a in ("%var%") do set "job=%%a"&set "desc=%%b"
echo "%job%" "%desc%" - correct? press enter to continue or N to start again:
set "var="
set /p "var="
if defined var goto :loop
md "n:\%job%\" 2>nul
setlocal enabledelayedexapansion
echo.
set c=0
for %%a in ("f:\cam-folder\*.jpg") do (
set /a c+=1
echo copying "n:\%job%\%desc%(!c!)%%~xa"
copy "%%a" "n:\%job%\%desc%(!c!)%%~xa" >nul
)
echo done
pause
#echo off
setlocal enableextensions enabledelayedexpansion
rem configuration
set "sourceFolder=w:\images"
set "targetFolder=n:\jobs"
rem test if there is something to copy
if not exist "%sourceFolder%\*.jpg" (
echo NO FILES FOUND
goto endProcess
)
:askJob
rem ask job number
set /p "jobNumber=Job Number : "
rem test if no job number
if "%jobNumber%"=="" (
echo NO JOB NUMBER - End of process
goto endProcess
)
rem test for existing job number
if exist "%targetFolder%\%jobNumber%" (
echo DUPLICATE JOB
goto askJob
)
rem ask for description
set /p "description=Description : "
rem test for no description
if "%description%"=="" (
echo NO DESCRIPTION - End of process
goto endProcess
)
rem WARNING - No test for valid job number nor valid description
rem WARNING - Don't shoot your own foot, or add code to validate
rem WARNING - according to your needs
rem create target job folder
set "target=%targetFolder%\%jobnumber%"
mkdir "%target%" > nul 2>nul
rem DO THE COPY
rem Generate a file list (dir), numerate it (findstr /n) and for each line
rem in generated list, split the number from the filename (for with delims)
rem and copy source file to numbered target file
for /f "tokens=1,* delims=:" %%f in ('dir /tc /od /b "%sourceFolder%\*.jpg" ^| findstr /n "^"') do (
echo transfer: "%sourceFolder%\%%g" == "%target%\%description%(%%f).*"
copy "%sourceFolder%\%%g" "%target%\%description%(%%f).*" >nul 2>nul
)
echo FILES COPIED
:endProcess
rem Clean
endlocal
rem and exit
exit /b
So, here's what I have: I created a small batch file to record the results of a ping test to a text file. What I want to do is run the batch file and move the results log to a specific folder on the Desktop automatically. Then, if the target filename exists, automatically rename accordingly. Meaning, if File1 exists, create File2, File3, so on and so forth. Here's what I have so far:
#echo off
color A
title Ping Test
:A
echo.
cls
ping google.com -n 4 > C:\Users\%username%\Desktop\pingresults.txt
cls
:Question
echo.
echo You can find the results in C:\Users\%username%\Desktop\pingresults.txt
echo Would you like to run this test again? (Y/N)
Set /p Choice=
if %choice% equ y goto :A
if %choice% equ n goto :Results
if %choice% neq y goto :Question
if %choice% neq n goto :Question
:Results
cls
echo Would you like to view the results of the test? (Y/N)
Set /p Choice=
if %choice% equ y goto :OpenResults
if %choice% equ n goto :Close
if %choice% neq y goto :Results
if %choice% neq n goto :Results
:Close
exit
:OpenResults
start C:\Users\%username%\Desktop\pingresults.txt
And the move batch file looks like this:
#echo off
echo.
cd C:\Users\Diesel\Desktop
move pingresults.txt PingResults\
if exist pingresults.txt ren pingresults.txt=+1
Exit.
I don't want to overwrite the existing file, but rename it in succession. I can't find any helpful articles anywhere using only batch files, they all say to use vbs or php, a language I'm not familiar with
To rename files to file1 [file2][...] and move it in a desktop folder:
#ECHO Off &SETLOCAL
FOR %%a IN (*.txt) DO CALL:processFile "%%~a"
goto:eof
:processFile
SETLOCAL
:loop
SET /a fileCounter+=1
SET "fileName=%~n1%filecounter%%~x1"
IF EXIST "C:\Users\%username%\Desktop\%fileName%" GOTO:loop
ECHO MOVE "%~1" "C:\Users\%username%\Desktop\%fileName%"
ENDLOCAL
goto:eof
Look at the output and remove the word echo before move if it looks good.
I have a pair of utility files that do this, so I can call from either command line, or another batch file. This manages several versions of the file in the same folder, and I would call it before moving your new file in.
Usage is:
archivefile 5 "c:\temp\songs" .txt [move]
Where 5 is the number of versions to keep.
The base file name in this example is "c:\temp\songs.txt"
and it creates (in c:\temp) 5 files: songs_1.txt songs_2.txt songs_3.txt songs_4.txt songs_5.txt
If you specify move it will move the original songs.txt otherwise it copies it.
Note, if you're using it from another batch file (which you'll probably want to), you need to use call or it won't return to your original batch file (both batch files will exit instead, which isn't what you want):
call archivefile 5 "c:\temp\songs" .txt
You need the pair of batch files to be either in the current directory, or on the windows path. Now I think about it, archivefile_b.bat could probably be a sub-routine within the main file instead, but it ain't broke, so I'm not going to fix it.
This is archivefile.bat:
#Echo off
rem archivefile.bat - keep a number of archives of a file
rem paramters: n rootfile extension [move|copy]
rem n = number of files to keep.
rem move|copy optional indicator to rename (move) the original file instead of copying it
rem archivefile 5 "c:\temp\songs" .txt [move]
rem
if "%3"=="" goto usage
set _af_n=%1
set _af_root=%2
set _af_ext=%3
set _af_move=copy
set _af_moveX=%4
if "%_af_moveX%"=="move" set _af_move=move
set _af_i=
set _af_j=
rem make sure that the first parameter (n) is numeric
set /A _af_n=%_af_n%
if "%_af_n%"=="0" echo Error: number of copies must be numeric (%1) & goto usage
if not exist %_af_root%%_af_ext% echo Error: cannot locate main file: %_af_root%%_af_ext% & goto error
rem remove the oldest file
if exist %_af_root%_%_af_n%%_af_ext% del %_af_root%_%_af_n%%_af_ext%
rem move up the remainder
for /L %%i in (%_af_n%, -1, 1) do call archivefile_b %%i %_af_root% %_af_ext%
rem copy the original
if "%_af_move%"=="move" goto moveIt
rem move not specified - make a copy
copy %_af_root%%_af_ext% %_af_root%_1%_af_ext%
goto moveCopyDone
:moveIt
rem need filename only for a rename
set _af_destfile=%_af_root%_1%_af_ext%
set _af_destfile=%_af_destfile:"=%
for %%i in (%_af_destfile%) do set _af_destfile=%%~ni%%~xi
ren %_af_root%%_af_ext% %_af_destfile%
:moveCopyDone
dir %_af_root%*%_af_ext%
goto done
:usage
echo usage: archivefile n rootfile extension
echo - n = number of archives to keep
echo - rootfile = the root filename
echo - extension = file extension
echo.
echo example:
echo archivefile 5 "c:\Documents and Settings\gregh\My Documents\Rescued document" .txt
goto done
:error
rem could maybe do something here? naa.
goto done
:done
This is archivefile_b.bat, which manages just one of the files:
rem #Echo off
rem archivefile_b.bat - helper for the archivefile routine
rem -- juggles ONE of the archive files.
rem paramters: n rootfile extension
rem n = the index to move from n to n+1
rem archivefile 5 "c:\temp\songs" .txt
rem therefore renames c:\temp\songs_5.txt to c:\temp\songs_6.txt
set _afb_n=%1
set _afb_root=%2
set _afb_ext=%3
rem make sure that the first parameter (n) is numeric
set /A _afb_n=%_afb_n%
if "%_afb_n%"=="0" echo Error: (archivefile_b) number of copies must be numeric (%1) & goto done
set /A _afb_j=%_afb_n%+1
rem define the file names
set _afb_fn=%_afb_root%_%_afb_n%%_afb_ext%
set _afb_fj=%_afb_root%_%_afb_j%%_afb_ext%
rem remove the quotes
set _afb_fn=%_afb_fn:"=%
set _afb_fj=%_afb_fj:"=%
rem can only supply a filename to the ren command (not path)
for %%i in (%_afb_fj%) do set _afb_fj=%%~ni%%~xi
rem do the rename now
if exist "%_afb_fn%" ren "%_afb_fn%" "%_afb_fj%"
:done