How to generate automatic numbering of output files in a batch file? - windows

I have a bunch of files say,
xxx111.txt
xxx112.txt
xxx113.txt
I want to remove the last 3 characters of all the file names and I'm using this script
#echo off
setlocal enabledelayedexpansion
set X=3
for %%f in (*) do if %%f neq %~nx0 (
set "filename=%%~nf"
set "filename=!filename:~,-%X%!"
ren "%%f" "!filename!%%~xf"
)
popd
pause
This runs perfectly when the output filenames are different. However, in the above case all file will be output as xxx.txt and the script throws me the error
"A duplicate file name exists, or the file cannot be found".
Is there any way to tweak this so that duplicate files will be renamed and maybe numbered 1,2,3...?
Unfortunately I cannot install any other software.

#echo off
setlocal EnableDelayedExpansion
set X=3
for /F "delims=" %%f in ('dir /A:-D /B') do if "%%f" neq "%~NX0" (
set "filename=%%~Nf"
set "filename=!filename:~,-%X%!"
if exist "!filename!%%~Xf" call :getNewName "%%~Xf"
ren "%%f" "!filename!%%~Xf"
)
popd
pause
goto :EOF
:getNewName ext
set i=0
:nextNum
set /A i+=1
if exist "%filename%%i%%~1" goto nextNum
set "filename=%filename%%i%"
exit /B
You should not use plain for %%f command when renaming files. Depending on where the new names are placed in the list of original names, they may be processed a second time by the for %%f. Always use for /F for renaming.

Related

How to rename only sub-folders without changing parent folder names

I have a folder containing several hundred sub-folders in the format Name, ID. Each of these folders contain several sub folders, some of which contain spaces in their names. I would like to rename only the sub folders and not the parent folders by replacing the spaces with underscores, e.g. C:\Location\John, 1234\My Documents to C:\Location\John, 1234\My_Documents.
I have tried modifying a piece of script I have found on here but it changes the parent folder as well
Here is the unedited code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "StartFolder=C:\Tydelik"
cd /D %SystemRoot%
set "RenameError="
rem Rename all folders containing at least one space character in folder name.
for /F "delims=" %%I in ('dir "%StartFolder%\* *" /AD /B /S 2^>nul') do call :RenameFolder "%%I"
if defined RenameError echo/& pause
rem Restore initial environment and exit this batch file.
endlocal
goto :EOF
:RenameFolder
set "NewFolderName=%~nx1"
set "NewFolderName=%NewFolderName: =_%"
set "FolderPath=%~dp1"
if not exist "%FolderPath%" set "FolderPath=%FolderPath: =_%"
set "FullFolderName=%FolderPath%%~nx1"
if not exist "%FullFolderName%\" set "RenameError=1" & goto :EOF
for %%J in ("%FullFolderName%") do set "FolderAttributes=%%~aJ"
if "%FolderAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe -h "%FullFolderName%"
ren "%FullFolderName%" "%NewFolderName%" 2>nul
if errorlevel 1 goto ErrorFolderRename
if "%FolderAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe +h "%FolderPath%%NewFolderName%"
goto :EOF
:ErrorFolderRename
echo Error renaming folder "%FullFolderName%"
set "RenameError=1"
if "%FolderAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe +h "%FullFolderName%"
goto :EOF
As I said the expected output for each sub folder should be C:\Location\John, 1234\My_Documents instead of C:\Location\John, 1234\My Documents. Currently with the code I have, I get C:\Tydelik\John,_1234\My_Documents.
While Compo's solution renames folders "depth=2", this renames just the "leafes" (very last folders of a tree, "depth=last"). I kept your call approach to avoid delayed expansion and resulting possible problems (folder names with ! - unlikely in your situation, but one never knows...)
#echo off
setlocal
set "sourcedir=..\..\"
for /f "delims=" %%I in ('dir "%sourcedir%" /ad /b /s 2^>nul') do call :RenameFolder "%%I"
goto :eof
:RenameFolder
dir /ad /b /s "%~1" 2>nul | find /v "" >nul && goto :eof ::skip renaming, if a subfolder exists
set "leaf=%~nx1"
ECHO ren "%~1" "%leaf: =_%"
goto :eof
Note: for security reasons I disabled the ren command by just echoing it. If it works as intended, remove the ECHO.
Here's an example of what I think you're looking for, based upon the fact that you're interested only in renaming subdirectories of "C:\Tydelik\Name, ID", not any contained within those subdirectories:
#Echo Off
SetLocal DisableDelayedExpansion
Set "SourceDir=C:\Tydelik"
For /F "EOL=?Delims=" %%A In ('Dir /B/AD "%SourceDir%" 2^>NUL'
)Do Set "TargetDir="&For /F "EOL=?Delims=" %%B In (
'Dir /B/AD "%SourceDir%\%%A" 2^>NUL') Do (Set "TargetDir=%%B"
SetLocal EnableDelayedExpansion
If Not "!TargetDir: =!"=="!TargetDir!" (
Ren "%SourceDir%\%%A\%%B" "!TargetDir: =_!")
EndLocal)

How can I modify this batch file so that it will add a number before the name of file and keep the caption as it is.?

#echo off
setlocal EnableDelayedExpansion
set i=0
for %%a in (*.jpg) do (
set /a i+=1
ren "%%a" "!i!.new"
)
ren *.new *.jpg
I have this batch file to rename all files in folder as 1,2,3...n But the problem is its removing the caption, I want to modify it such that it will keep the caption as it is and will just add a number before a caption.
#Echo Off
SetLocal EnableDelayedExpansion
Set "i=0"
For %%A In (*.jpg) do (Set /A i+=1
Ren "%%A" "!i!%%~nA.new"
)
Ren *.new *.jpg
The filename plus extension above is %%A and the filename without extension is %%~nA. So I used Ren "%%A" "!i!%%~nA.new". Please refer to the help usage of the For command for a full explanation, enter For /? at the Command Prompt to do so.
You can separate the !i! from the %%~nA with a character of your choosing too!

Batch file rename multiple files only echos the result

I was having an issue with creating a batch file (.bat) to rename multiple files in the same directory based on specific parameters. In order to make it happen for multiple files I had to add an incremental value to it.
From research(mostly here) I pieced together the below command, but whatever I do I cannot actually get to do it. It just echos what's supposed to do and when I remove the echo from before 'ren' it says bad syntax.
#echo off
CD C:\FolderPath\
setlocal enabledelayedexpansion
set /a count=0
for /f "tokens=*" %%a in ('dir /b /od *.txt') do (
echo ren CDFF_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%%time:~9,2%_!count!.txt
set /a count+=1
)
Add the first parameter to ren command (the file to rename):
ren "%%a" "CDFF_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%%time:~9,2%_!count!.txt"
So the whole code is:
#echo off
setlocal enabledelayedexpansion
CD C:\FolderPath\
set /a count=0
for /f "tokens=*" %%a in ('dir /b /od *.txt') do (
echo ren "%%a" "CDFF_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%%time:~9,2%_!count!.txt"
set /a count+=1
)
Please note it will not work for files with weird names. Eg. "File( name.txt"
ren requires the input filname as its first argument. Hence your syntax error.
Here is an alternative implementation:
#echo off
setlocal enabledelayedexpansion
set FOLDER=%1
set DATE=%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%%time:~9,2%
set /a count=0
for /r %FOLDER% %%a in (*.txt) do (
ren "%%a" CDFF_%DATE%_!count!.txt
set /a count += 1
)
call as
rename.bat C:\FolderPath

Batch rename files how to loop in order of filename?

I have a bunch of jpg files named IMG_0001, IMG_0002, etc. The problem was that there I had to delete a couple of them, so I need to rename the files to fill in the gaps. In essence,
IMG_0001, IMG_0002, IMG_0004, IMG_0006
are renamed
IMG_0001, IMG_0002, IMG_0003, IMG_0004.
Thus filling in the gaps caused by the files I deleted. However, the bat file I wrote to do this sometimes jumbles the files out of order, so what was originally IMG_0001 would become IMG_0002, and IMG_0003 would become IMG_0001. How can I ensure that my bat file loops through the files in order of name?
This is my bat file:
#echo off
set i=1
set y=0000
for %%f in (*.jpg) do call :renameit "%%f"
goto done
:renameit
set x=%y%%i%
ren %1 IMG_%x:~-4%.jpg
set /A i+=1
:done
I don't think FOR supports ordering on its own, but DIR does with the /on ("order by name") switch. So, try replacing your FOR loop with this:
for /f "tokens=*" %%f in ('dir /b /on *.jpg') do call :renameit "%%f"
#echo off
setlocal enableextensions enabledelayedexpansion
for /f "tokens=1,* delims=:" %%a in ('dir /a-d /on /b "IMG_*.jpg"^|findstr /n "^"') do (
set /a "n=%%a+10000"
ren "%%b" "IMG_!n:~-4!.jpg"
)
This just uses findstr to numerate the list of retrieved files (each lines is in the format number:filename) and uses this numeration to do the rename of files.

How to rename multiple files using a windows batch file script

I have and will have files which are named "x_1.txt x_2.txt x_3.txt, ..." my other program where I input these files cannot recognize the order so it sorts like this "x_1.txt , x_101.txt , x_2.txt"). a solution is to rename the files to x00001.txt , x00002.txt , ....
I have so far wrote the .bat file below, but two problems I have which , I'd be very glad if you help me solve them :
1- how can I remove the 'number'.txt from string x_'number'.txt
2- (solved) how can I use the variable of this string to rename the file name ( the rename part of this file is not working!)
cls
setlocal enabledelayedexpansion
set /A count=100000
for %%f in (*.txt) do (
set /a count+=1
set str=!count:~1!
echo !str!
echo %%f
set filename=%%f
set filename=!filename:~0,5! /Comment: here I want to just keep the x_ part which I don't know how"
echo !filename!
set str3=!filname!!str!
echo !str3!
/// ren %%f !str3!.txt /Comment: Here I cannot use the variable str3,
call:renamer %%f !str3!
)
:renamer
ren %1 %2.txt
Thanks in advance
If the following conditions are true:
You want to rename all of your .txt files in the current folder
All of the .txt files have exactly one _ in the name, immediately before the number
None of your file names contain !
Then the following will work
#echo off
setlocal enableDelayedExpansion
for %%F in (*.txt) do for /f "tokens=1,2 delims=_." %%A in ("%%F") do (
set num=0000%%B
ren "%%F" "%%A!num:~-5!.txt"
)
But to eliminate the conditions requires much more complicated code.
Here is one robust solution that should properly rename all files that meet the template.
It allows for multiple _ in the name.
It only renames files with a name that ends with _NNN.txt where NNN is a number
It properly handles ! in the file name.
Note that it will not properly handle numbers that exceeds 99999. It is simple to expand the degree of 0 padding.
#echo off
setlocal disableDelayedExpansion
pushd .
subst #: .
#:
for /f "eol=: delims=" %%F in ('dir /b /a-d *.txt^|findstr /er "_[0-9]*.txt"') do (
set "name=%%~nF"
setlocal enableDelayedExpansion
for /f "eol=: delims=" %%A in ("!name:_=\x!") do (
endlocal
set "file=%%F"
set "name=%%~pA"
set "num=%%~nA"
setlocal enableDelayedExpansion
set "num=0000!num:~1!"
set "name=!name:~1,-1!"
ren "!file!" "!name:\x=_!!num:~-5!.txt"
endlocal
)
)
popd
subst /d #:

Resources