Batch file increment folder number - batch-file

I'm trying to create a batch file that creates folders 1.2.0.1, 1.2.0.2,1.2.0.3, etc.
I fould this code from a previous question and it almost works for my needs:
#echo off
setlocal enableDelayedExpansion
set "baseName=New_Folder"
set "n=0"
for /f "delims=" %%F in (
'2^>nul dir /b /ad "%baseName%*."^|findstr /xri "%baseName%[0-9]*"'
) do (
set "name=%%F"
set "name=!name:*%baseName%=!"
if !name! gtr !n! set "n=!name!"
)
set /a n+=1
md "%baseName%%n%"
so the way I attempted it is to have two variables, one holds the first three digits 2.4.0 and the other holds the forth one.
set version=1.2.0
cd C:\Users\Build
set "lastFolder=0"
for /f "delims=" %%F in (
'2^>nul dir /b /ad "%version%*."^|findstr /xri "%version%[0-9]*"'
) do (
set "name=%%F"
set "name=!name:*%version%=!"
if !name! gtr !lastFolder! set "lastFolder=!name!"
)
set /a nextFolder=lastFolder+1
md "%version%.%nextFolder%"
but this doesn't work because it's only creating the first folder and not the ones following. Can anyone help me determine the issue? Thanks

This will create folders, if they exist or not.
#echo off
for /L %%a in (1,1,255) do MD "1.2.0.%%a" 2>nul
This should create only the next folder in the series:
#echo off
cd C:\Users\Build
for /L %%a in (1,1,20000000) do if not exist "1.2.0.%%a\" MD "1.2.0.%%a" & goto :done
:done
This is your code that now works - and it does exactly the same as the code above, within reason. 2 million folders seems to be a fair number, even if it takes a few seconds. :)
#echo off
setlocal enabledelayedexpansion
set version=1.2.0.
cd C:\Users\Build
set "lastFolder=0"
for /f "delims=" %%F in (
'2^>nul dir /b /ad "%version%*."^|findstr /xri "%version%[0-9]*"'
) do (
set "name=%%F"
set "name=!name:*%version%=!"
if !name! gtr !lastFolder! set "lastFolder=!name!"
)
set /a nextFolder=lastFolder+1
md "%version%%nextFolder%"
pause

Missing ! and . is not being correctly handled:
...
'2^>nul dir /b /ad "%version%.*"^|findstr /xri "%version%.[0-9]*"'
...
set "name=!name:*%version%.=!"
...
set /a nextFolder=!lastFolder!+1
...

Related

Batch file to replace special characters in subfolder in windows

#echo off
FOR /f "delims=" %%G IN ('dir /a-d /b /s /o-n ^|sort /r') DO (
setlocal enabledelayedexpansion
pushd "%%~dpG"
SET Var=%%~nfG
SET Var=!Var: =_!
SET Var=!Var:[=_!
SET Var=!Var:]=_!
SET Var=!Var:(=_!
SET Var=!Var:)=_!
SET Var=!Var:,=_!
SET Var=!Var:'=_!
rename "%%~nfG" "!Var!"
popd
endlocal
)
Not working getting error in prompt like
_! was unexpected at this time.
Can anyone answer or correct this plz.enter code here
Also I'd compare if the name is changed before trying to rename:
:: Q:\Test\2017\08\05\SO_45521689.cmd
#echo off
FOR /f "delims=" %%G IN (
'dir /a-d /b /s /o-n ^|findstr "[,'()\[\]]"^|sort /r'
) DO (
setlocal enabledelayedexpansion
pushd "%%~dpG"
SET "Var=%%~nfG"
SET "Var=!Var: =_!"
SET "Var=!Var:[=_!"
SET "Var=!Var:]=_!"
SET "Var=!Var:(=_!"
SET "Var=!Var:)=_!"
SET "Var=!Var:,=_!"
SET "Var=!Var:'=_!"
if "%%~nfG" neq "!Var!" rename "%%~nfG" "!Var!"
popd
endlocal
)
SET Var=!Var:)=_!
rem ↑ this closing parenthesis closes the `... DO ()` code block.
Use
SET "Var=!Var:)=_!"
or
SET Var=!Var:^)=_!
Moreover, you cannot specify a drive or path for rename target. Use SET "Var=%%~nxG" instead of SET Var=%%~nfG.
Be aware of that your script ingurgitates all exclamation marks if a file name contains any.
The following script should do the job keeping delayed expansion disabled. Please note that operational rename command is merely ECHOed for debugging purposes.
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
rem choose initial directory
pushd "D:\bat\Unusual Names"
FOR /f "delims=" %%G IN ('dir /a-d /b /s /o-n') DO (
SET "_FFN=%%~fG" File Full Name
SET "Var=%%~nxG" File Name + Extension
call :renaming
)
popd
ENDLOCAL
goto :eof
:renaming
SET "Var=%Var: =_%"
SET "Var=%Var:[=_%"
SET "Var=%Var:]=_%"
SET "Var=%Var:(=_%"
SET "Var=%Var:)=_%"
SET "Var=%Var:,=_%"
SET "Var=%Var:'=_%"
ECHO rename "%_FFN%" "%Var%"
goto :eof

Intuitive file sorting in batch scripts?

So in Windows Explorer, I have these files sorted like this:
I have this script to remove the brackets and one zero, and in case the trailing number is greater than or equal to 10, to remove two zeroes:
cd C:\folder
setlocal enabledelayedexpansion
SET /A COUNT=0
for %%a in (*.jpg) do (
SET /A COUNT+=1
ECHO !COUNT!
set f=%%a
IF !COUNT! GTR 9 (
set f=!f:^00 (=!
) ELSE (
set f=!f:^0 (=!
)
set f=!f:^)=!
ren "%%a" "!f!"
)
pause
However, once I run the code, I get this result:
So the batch file isn't going through the files "intuitively" like Windows Explorer shows them. Is there any way to change this? Or is there a better way to rename these files altogether?
This uses a different approach:
#echo off
cd C:\folder
setlocal enabledelayedexpansion
SET /A COUNT=0, REMOVE=2
for /F "delims=(" %%a in ('dir /B *.jpg') do (
SET /A COUNT+=1
ECHO !COUNT!
set "f=%%a"
IF !COUNT! EQU 10 SET "REMOVE=3"
for /F %%r in ("!REMOVE!") do set "f=!f:~0,-%%r!"
ren "%%a" "!f!!COUNT!.jpg"
)
pause
Here is a method that does not depend on the sort order used by the file system, preserving the numbers as occurring in the original file names.
For each file name (for instance, test_this_01 SELR_Opening_00000 (1).jpg), the portion after the last under-score _ is retrieved (00000 (1)). Then the parentheses and the space are removed and then the length is trimmed to five characters (00001). This string replaces the original one in the file name finally (test_this_01 SELR_Opening_00001.jpg); the file name must not contain the replaced portion (00000 (1)) multiple times (hence file names like this should not occur: test_this_00000 (1) SELR_Opening_00000 (1).jpg):
#echo off
setlocal DisableDelayedExpansion
rem // Define constants here:
set "LOCATION=."
set "PATTERN=*_* (*).jpg"
set /A "DIGITS=5"
pushd "%LOCATION%" || exit /B 1
for /F "usebackq eol=| delims=" %%F in (`
dir /B /A:-D /O:D /T:C "%PATTERN%"
`) do (
set "FILE=%%F"
setlocal EnableDelayedExpansion
set "LAST="
for %%I in ("!FILE:_=","!") do (
set "LAST=%%~nI" & set "FEXT=%%~xI"
set "FNEW=!FILE:%%~I=!"
)
set "LAST=!LAST:(=!" & set "LAST=!LAST:)=!"
set "LAST=!LAST: =!" & set "LAST=!LAST:~-5!"
ECHO ren "!FILE!" "!FNEW!!LAST!!FEXT!"
endlocal
)
popd
endlocal
exit /B
Adapt the directory location and the file search pattern in the top section of the script as you like.
After having tested, remove the upper-case ECHO command in order to actually rename files.

Command line counter not incrementing

Hi I have a batch script to move x amount of files from one folder to another. The counter that count the files moved is not incrementing. The script is as follows
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
echo on
set DataMax=50
set Counter=1
set SrcMax=50
set DataLoc=Destination Folder
Set HoldLoc=Source Folder
set count=0
FOR /F %%a in ('DIR /B %DataLoc%\*.pst') do set /A count=count+1
if %count% GEQ %DataMax% (Goto Exit) else (GOTO FMove)
:FMove
Echo Gather Top 50 files
FOR /F "TOKENS=*" %%a IN ('dir /A-D /O-D /B %HoldLoc%\*.pst') DO (
if %Counter% LEQ %SrcMax% (
MOVE /y %HoldLoc%\%%a %DataLoc%\
SET /A Counter += 1
)
)
goto Exit
:Exit
exit
The Set /A Counter += 1 does not seem to work. Thanks in Advance for any assistance.
As you already have enabled delayed expansion try like:
FOR /F "TOKENS=*" %%a IN ('dir /A-D /O-D /B %HoldLoc%\*.pst') DO (
if !Counter! LEQ %SrcMax% (
MOVE /y %HoldLoc%\%%a %DataLoc%\
SET /A Counter=Counter+1
)
)
npockmaka has shown how to get your code to work under normal circumstances by using delayed expansion. However, it will fail if any files names contain the ! character (unlikely, but it could happen)
It is possible to make the code work without delayed expansion by intentionally dividing by zero when the maximum count is exceeded. The error message is hidden by redirecting to nul, and the || operator detects the error and conditionally executes the EXIT command.
I also streamlined the first loop to use FIND to quickly get the count, instead of iterating each file.
#echo off
setlocal
set /a count=0, SrcMax=DataMax=50
set "DataLoc=Destination Folder"
set "HoldLoc=Source Folder"
for /f %%N in (
'dir /b "%DataLoc%\*.pst"^|find /c /v ""'
) do if %%N geq %DataMax% exit /b
echo Gather Top 50 files
for /f "eol=: delims=" %%A in (
'dir /a-d /o-d /b "%HoldLoc%\*.pst"'
) do (
set /a "1/(SrcMax-count), count+=1" 2>nul || exit /b
move /y "%HoldLoc%\%%B" "%DataLoc%\"
)
Another option is to number each file via FINDSTR /N, and let FOR /F parse out the number and file name.
#echo off
setlocal
set /a SrcMax=DataMax=50
set "DataLoc=Destination Folder"
set "HoldLoc=Source Folder"
for /f %%N in (
'dir /b "%DataLoc%\*.pst"^|find /c /v ""'
) do if %%N geq %DataMax% exit /b
echo Gather Top 50 files
for /f "tokens=1* delims=:" %%A in (
'dir /a-d /o-d /b "%HoldLoc%\*.pst"^|findstr /n "^"'
) do (
if %%A gtr %SrcMax% exit /b
move /y "%HoldLoc%\%%B" "%DataLoc%"
)
There is one thing that concerns me in your logic.
If you already have 50 files in your destination, then you exit without doing anything. If you do not yet have 50 files, then you move up to 50 files from the source to the destination. If there are 49 files in the destination at the start, then there is the potential to end up with 99 files in the destination, assuming none of the moved file names match the existing files in the destination.

Change File Name to Folder Name

I've been working on a batch script (.bat) to change file name to the same folder name 3 levels up but no luck. I can only get it to rename 1 level up. There are multiple files in multiple folders.
Any help would be greatly appreciated.
I don't completely understand the intent of your current code. But the following will rename a given file based on the folder 3 levels up. Note that you can only rename one file with a given extension per folder using this strategy.
#echo off
setlocal
set "file=H:\Techs\Exported Videos\Scenario\1-CAS IED\Media player format\A8 West\abc.avi"
for %%A in ("%file%") do for %%B in ("%%~A\..\..\..") do ren "%%~A" "%%~nxB%%~xA"
Note that I include the extension of the folder name because folder names can include dots.
EDIT
Based on OP's comments, I believe the following will properly rename all relevant .avi files. The code has been tested, and works in my hands. Simply set the root and files values as appropriate.
#echo off
setlocal
set "root=H:\Techs\Exported Videos\Scenario"
set "files=*.avi"
for %%A in ("%root%\.") do set "root=%%~fA"
for /f "delims=" %%A in ('dir /b /s /a-d "%root%\%files%"') do (
for %%B in ("%%~A\..\..\..") do (
if /i "%%~dpB" equ "%root%\" ren "%%~A" "%%~nxB%%~xA"
)
)
you might try this:
#echo off &setlocal
set /a PathLevel=3
for %%a in (
"H:\Techs\Exported Videos\Scenario\1-CAS IED\Media player format\A8 West\1-CAS IED.avi"
"H:\Techs\Exported Videos\Scenario\2-SAF\Media player format\A8 PTZ\2-SAF.avi"
) do (
call:doit "%%~a"
)
goto:eof
:doit
set "fname=%~1"
set /a cnt=0
for %%a in ("%fname:\=","%") do set /a cnt+=1
set /a cnt-=PathLevel
for %%a in ("%fname:\=","%") do (
set /a cnt-=1
setlocal enabledelayedexpansion
if !cnt! equ 0 (
endlocal
set "nname=%%~a"
) else endlocal
)
echo ren "%fname%" "%nname%%~x1"
goto:eof
output is:
ren "H:\Techs\Exported Videos\Scenario\1-CAS IED\Media player format\A8 West\1-CAS IED.avi" "1-CAS IED.avi"
ren "H:\Techs\Exported Videos\Scenario\2-SAF\Media player format\A8 PTZ\2-SAF.avi" "2-SAF.avi"

Rename files in sub directories using sub directory name with incremental number restarting for each sub directory

I have a few directories, named "A", "B", "C", and so on. Each has some files in it. I like to rename files in each directory using directory name plus an index number starting with 1 in each directory, with left-zero padded to the width of 3. For example:
Sub directory A has 3 files, and they'll be renamed as:
A_001.dat
A_002.dat
A_003.dat
Sub directory B has 2 files, and they should be renamed as:
B_001.dat
B_002.dat
and so on. These files will be moved to the main directory. I have the following batch file, but I can't seem to increment the number. Please help.
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=DAT
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
set i=1
for /f "delims=" %%b in ("%%~dpa\.") do (
set pad=00!i!
set str=!pad:~-3!
echo move /b "%%a" "%HomeFolder%\%%~nxb_!str!.%NewExt%"
set /A i=!i!+1
)
)
endlocal
pause
And the correct answer is:
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=TIF
set i=1
set Folder=
set LastFolder=
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
for /f "delims=" %%b in ("%%~dpa\.") do (
set Folder=%%~nxb
if NOT !Folder!==!LastFolder! (set /A i=1)
set LastFolder=!Folder!
set pad=00!i!
set str=!pad:~-3!
copy /b "%%a" "%HomeFolder%\%%~nxb_!str!.%NewExt%"
Set /A i+=1
)
)
endlocal
In a loop or parenthetical expression you need to use a delayed expansion
set /a variable=!variable!+1
But you need to activate this feature with setlocal ENABLEDELAYEDEXPANSION and reset it with a matching endlocal
Try the following:
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=DAT
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
set i=1
for /f "delims=" %%b in ("%%~dpa\.") do (
set pad=00%i%
set str=%pad:~-3%
echo move /b "%%a" "%HomeFolder%\%%~nxb_%str%.%NewExt%"
set /A i+=1
)
)
endlocal
pause
#echo off
:: By Elektro H#cker
Setlocal enabledelayedexpansion
set "OldExt=TXT"
set "NewExt=DAT"
FOR /R %%# in (*%OldExt%) DO (
REM Sets the directory of the file
Set "Directory=%%~dp#"
REM Cuts the directory name to obtain the last folder name
Set "Directory=!Directory:~0,-1!"
For /L %%X in (0,1,50) DO (Call Set "Directory=!Directory:*\=!")
REM Check if this directory is the same of the last accesed directory to reset the counter or not
Echo "!Directory!"|FINDSTR "^\"!LastDirectory!\"$" >NUL && (Set /A "Count+=1") || (Set /A "Count=1")
REM Check if the number incrementation have 1-3 digits and copies the file
Call Echo !COUNT!|FINDSTR "^[0-9]$" >NUL && (Call Copy "%%#" ".\!Directory!_00!COUNT!.%NewExt%")
Call Echo !COUNT!|FINDSTR "^[0-9].$" >NUL && (Call Copy "%%#" ".\!Directory!_0!COUNT!.%NewExt%" )
Call Echo !COUNT!|FINDSTR "^[0-9]..+$" >NUL && (Call Copy "%%#" ".\!Directory!_!COUNT!.%NewExt%" )
REM Sets the last accesed directory
Call Set "LastDirectory=!Directory!"
)
Pause&exit
3 subdirs named "A" "B" and "C", 3 files inside of each subdir, the output result is:
a_001.DAT
a_002.DAT
a_003.DAT
b_001.DAT
b_002.DAT
b_003.DAT
c_001.DAT
c_002.DAT
c_003.DAT
Here is the working script for whoever wants to do the same thing:
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=DAT
set i=1
set Folder=
set LastFolder=
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
for /f "delims=" %%b in ("%%~dpa\.") do (
set Folder=%%~nxb
if NOT !Folder!==!LastFolder! (set /A i=1)
set LastFolder=!Folder!
set pad=00!i!
set str=!pad:~-3!
copy /b "%%a" "%HomeFolder%\%%~nxb_!str!.%NewExt%"
Set /A i+=1
)
)
endlocal

Resources