Renaming files sequentially with 4 digits - .bat - windows

I'm looking for a solution to my problem, below the script I'm using, I found it here, changed it, it was working the way I wanted to for what I was doing but now I want to do that and I'm struggling with the answer.
Example:
<br>Open_university_MS221_0001.tif</br>
<br>Open_university_MS221_0001-2.tif</br>
<br>Open_university_MS221_0002.tif</br>
<br>Open_university_MS221_0002-2.tif</br>
<br>etc.</br>
<br>Open_university_MS221_0001.tif</br>
<br>Open_university_MS221_0002.tif</br>
<br>Open_university_MS221_0003.tif</br>
<br>Open_university_MS221_0004.tif</br>
<br>etc.</br>
#echo off
setlocal enableextensions enabledelayedexpansion
set /a count=1
for %%f in (*.tif) do (
set FileName=%%~nf
set FileName=000!count!
set FileName=!FileName:~-4!
for /F "tokens=1-3 delims=_+" %%g in ('dir /b /od *.tif') do (
set prefix=%%g_%%h_%%i
)
set FileName=!prefix!_!Filename!%%~xf
rename "%%f" "!FileName!"
set /a count+=1
)

Working solution below, thanks to aschipfl who did show me the way and Stephan
#echo off
setlocal enableextensions enabledelayedexpansion
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please choose a folder.',0,0).self.path""
for /f "usebackq delims=" %%i in (`powershell %psCommand%`) do set "folder=%%i"
cd %folder%
set path=%folder:~1%
for %%i in ("%path%") do (
set "parent=%%~ni"
)
set /a count=10000
for /F "eol=| delims=" %%f in ('dir /B /A:-D-H-S /O:N "*.tif"') do (
set /a count+=1
set fileName=!parent!_!count:~-4!%%~xf
rename "%%f" "!fileName!"
)
exit /b

You can get rid of a lot of code within the loop, when you initialize the counter to 10000 before entering the loop. Then within the loop, you just use !count:~-4!
#echo off
setlocal enableextensions enabledelayedexpansion
set /a count=10000
for %%f in (*.tif) do (
for /F "tokens=1-3 delims=_+" %%g in ('dir /b /od *.tif') do (
set prefix=%%g_%%h_%%i
)
set /a count+=1
set FileName=!prefix!_!count:~-4!%%~xf
rename "%%f" "!FileName!"
)
The code could be shortened even more but at the cost of readability.
Oh - and I moved set /a count+=1 up to avoid starting with 0000 (your example shows, you don't want that)

Related

File count and size of each folder

I have the following batch script which gives the size of each folder in a directory. I need help in tweaking this or creating a new script so it gives the file count of each folders as well:
#echo off
setlocal disabledelayedexpansion
set "folder=%~1"
if not defined folder set "folder=%cd%"
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
endlocal
All the information is already in the output of the inner dir command, you only need to change what to retrieve
#echo off
setlocal disabledelayedexpansion
for %%a in ("%~f1.") do set "folder=%%~fa"
for /d %%f in ("%folder%\*") do (
set /a "size=0", "files=0", "directories=0"
for /f "tokens=1,3,5" %%a in ('
dir /-c /a /w /s "%%~ff\*" 2^>nul ^| findstr /b /c:" "
') do if "%%~c"=="" (
set "files=%%~a"
set "size=%%~b"
) else set /a "directories=%%~a/3"
setlocal enabledelayedexpansion
echo(%%~nxf # !size! bytes : !files! files : !directories! directories
endlocal
)
Add this cmd at the end and it will count files in a given dir
setlocal enableextensions
set count=0
for %%x in ("%folder%\*") do set /a count+=1
echo %count%
endlocal
This is inefficient tho, as you are traversing the whole directory twice.
Ideally, you need to combine the two FOR loops into one, just scan the dir once and add the size to the size counter and do count+=1 for each.
Try something like *added spacing to show what i added
set "folder=%~1"
if not defined folder set "folder=%cd%"
set count=0
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
set /a count+=1
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
echo %count%
endlocal

How to find subdirectories of only two levels deep?

I got a script that lists all subdirectories in a folder and put them in a file:
dir "\\test\e$\1" /a:d /s /b | sort>"C:\folders.txt
effect looks like this:
\\test\e$\1
\\test\e$\1\target1
\\test\e$\1\target1\in
\\test\e$\1\target1\out
\\test\e$\1\target2
\\test\e$\1\target2\in
\\test\e$\1\target2\out
\\test\e$\1\target3
\\test\e$\1\target3\in
\\test\e$\1\target3\out
\\test\e$\2
\\test\e$\2\target1
\\test\e$\2\target1\in
\\test\e$\2\target1\out
\\test\e$\2\target2
\\test\e$\2\target2\in
\\test\e$\2\target2\out
\\test\e$\2\random_folder_without_in_subfolder
what I really need:
\\test\e$\1\target1
\\test\e$\1\target2
\\test\e$\1\target3
\\test\e$\2\target1
\\test\e$\2\target2
even better (if possible) in this form (separator: "|:"):
\\test\e$\1\target1|:\\test\e$\1\target2|:\\test\e$\1\target3|:\\test\e$\2\target1|:\\test\e$\2\target2
#ECHO OFF
SETLOCAL
SET "sourcedir=."
FOR /f "delims=" %%a IN ('dir /s /b /ad "%sourcedir%" '
) DO (
FOR /f "tokens=3,4delims=\" %%d IN ("%%a") DO IF "%%e"=="" (ECHO(%%a) ELSE GOTO secondway
)
:secondway
#ECHO off
SETLOCAL enabledelayedexpansion
SET "sourcedir=."
SET "longline="
FOR /f "delims=" %%a IN ('dir /s /b /ad "%sourcedir%" '
) DO (
FOR /f "tokens=3,4delims=\" %%d IN ("%%a") DO IF "%%e"=="" (
SET "longline=!longline!|:%%a"
) ELSE GOTO done2
)
:done2
SET "longline=!longline:~2!"
SET longline
FOR /f "tokens=1*delims==" %%a IN ('set longline') DO ECHO %%b
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
May have problems with directorynames containing characters that have a special meaning to cmd.

count length of filenames in batch

my problem is I want to count the length of multiple filenames and save this numbers into a file.
My approach is this:
#echo off
for %%i in (*.txt) do (
set Datei=%%~ni
call :strLen Datei strlen
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
echo.%strlen%>> tmp
)
The problem here is it only works for the first filename and after that it is stuck and does not go on to the next filename.
Just for another alternative, findstr can output the offset of each matching line. Using it over the dir output and substracting the offset of the previous line from the current one (and the CRLF at the end of the line), we get the length of the previous line / file name
#echo off
setlocal enableextensions disabledelayedexpansion
set "lastOffset=0"
for /f "tokens=1,* delims=:" %%a in ('(dir /b *.txt ^& echo(^) ^| findstr /o "^"') do (
if %%a gtr 0 (
set /a "size=%%a - lastOffset - 2"
setlocal enabledelayedexpansion
echo(!fileName! !size!
endlocal
)
set "lastOffset=%%a"
set "fileName=%%b"
)
Just for another alternative of a one-line command:
for %# in (*.txt) do #for /F "delims=:" %G in ('(echo "%~f#"^&echo(^)^|findstr /O "^"') do #if %~G NEQ 0 ( <^NUL set /p "dummy=%~f#|%~z#|"&set /a %~G-5&echo()
or the same in a bit more readable form:
for %# in (*.txt) ^
do #for /F "delims=:" %G in ('(echo "%~f#"^&echo(^)^|findstr /O "^"') ^
do #if %~G NEQ 0 ( <^NUL set /p "dummy=%~f#|%~z#|"&set /a %~G-5&echo()
Unfortunately, unlike the cmd shell, set command does not display its result in a batch script. Therefore, we need to set a string length to an environment variable and then echo its value with delayed expansion enabled:
#ECHO OFF >NUL
SETLOCAL EnableExtensions EnableDelayedExpansion
rem file lengths:
rem for %%A in (*.txt) do echo Name:%%A, Length: %%~zA
rem full path lengths:
for %%# in (*.txt) do (
for /F "delims=:" %%G in ('(echo "%%~f#"^&echo(^)^|findstr /O "^"') do (
if %%~G NEQ 0 (
set /a "length=%%~G-5"
rem echo(%%~f#^|%%~z#^|!length!
echo(%%~f#^|!length!
)
)
)
A slightly modified how to do count length of file name.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
(
for /f "tokens=*" %%A in ('dir *.txt /B /S /A:-D ^| findstr /IV "_output.txt"') do (
set "name=%%~nA"
#echo "!name!">"%TMP%\_Temp.txt"
for %%I in ("%TMP%\_Temp.txt") do (
set /a "length=%%~zI"
set /a length-=4
#echo !length!:'!name!'
)
)
)> _output.txt 2>&1
del "%TMP%\_Temp.txt"
MORE /C /P _output.txt
ENDLOCAL
EXIT /B 0
well the solution was coming from you i just moved the parts out of the loop. the code is this:
#echo off
for %%i in (*.txt) do (
set Datei=%%~ni
call :strLen Datei strlen
)
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1
goto :strLen_Loop
(endlocal & set %2=%len%)
echo.%strlen%>> tmp

windows batch increment in specific alphanumeric string

I have a SOURCE textfile in which I wanted to manipulate add an incrementing alphanumerical before the semicolon as below and outputs OUTPUT.txt
SOURCE:
2:apple,coconut,cherry;
3:banana,mango;
4:cereals,nuts;
.......... and so on
DESIRED OUTPUT:
2:apple,coconut,cherry,TP001;
3:banana,mango,TP002;
4:cereals,nuts,TP003;
.........and so on
----------
so I came up with the below script but it is just replacing every semicolon with ,TP001;,
can someone please help me how can I make increments to the TP001~ and so on as my desired output.
#echo off
setlocal enabledelayedexpansion
set txtfile=%1
set newfile=OUTPUT.txt
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
set newline=%%a
set newline=!newline:^;=^,TP001;!
echo !newline! >> %newfile%
)
I hope you can help me with this. thank you...
#echo off
setlocal enabledelayedexpansion
set "txtfile=%~1"
set "newfile=OUTPUT.txt"
break > "%newfile%"
set "count=1000"
(for /f "usebackq delims=;" %%a in ("%txtfile%") do (
set /a "count+=1"
echo(%%a,TP!count:~-3!
))>"%newfile%"
Here you go:
#echo off
setlocal enabledelayedexpansion
set txtfile=%1
set newfile=OUTPUT.txt
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
set newline=%%a
set /a "inc+=1"
set num=00!inc!
set num=!num:~-3!
set newline=!newline:^;=^,TP!
echo !newline!!num!; >> %newfile%
)
Your data has a trailing space so the code removes two characters from the end of each line.
#echo off
setlocal enabledelayedexpansion
set "txtfile=%~1"
set "newfile=OUTPUT.txt"
set c=0
if exist "%newfile%" del /f /q "%newfile%"
for /f "usebackq delims=" %%a in ("%txtfile%") do (
set /a c+=1
set "n=000!c!"
set "n=!n:~-3!"
set "line=%%a"
set "line=!line:~0,-2!
>>"%newfile%" echo !line!,TP!n!;
)

Comparing the number of files in two folders

I want to verify that two folders have the same number of files.
For example if there are 5 files in folder c:\Users\abc\INBOX, I want to verify that there are also 5 files in folder c:\Users\abc\OUTBOX
How can I achieve this?
#echo off
setlocal enableextensions disabledelayedexpansion
call :getNumberOfFilesInFolderList nINBOX "c:\Users\abc\INBOX"
call :getNumberOfFilesInFolderList nFiles "c:\Users\abc\OUTBOX" "c:\Users\abc\OUTBOX\PROC" "c:\Users\abc\OUTBOX\PEND"
if %nINBOX% EQU %nFiles% (
echo SAME number of files
) else (
echo DIFFERENT number of files
)
endlocal
exit /b
:getNumberOfFilesInFolderList variable folder1 [[folder2] ... ]
setlocal enableextensions disabledelayedexpansion
set "variable="
set /a "total=0"
for %%a in (%*) do if not defined variable (set "variable=%%~a" ) else (
for /f %%b in ('dir /a-d "%%~a" 2^>nul ^| findstr /r /c:"^[ ][ ][ ]*[0-9]"') do set /a "total+=%%b"
)
endlocal & set "%~1=%total%" & echo %total%
goto :eof
This should compare two folders.
#echo off
set aa=0&set bb=0
for %%a in ("c:\Users\abc\INBOX\*") do set /a aa+=1
for %%a in ("c:\Users\abc\OUTBOX\*") do set /a bb+=1
if %aa% EQU %bb% (
echo they have the same number of visible files.
) else (
echo the file count is different
)
TRy something like this :
#echo off
set $Folder1="c:\Users\abc\INBOX"
set $folder2="c:\Users\abc\OUTBOX"
set $count=1
setlocal EnableDelayedExpansion
for %%x in (%$Folder1% %$Folder2%) do (
for /f "tokens=1 delims= " %%a in ('dir %%x ^| find /i "File(s)"') do (
set $Total!$Count!=%%a)
set /a $Count+=1)
If %$Total1% Equ %$Total2% (echo Same number of files) else (echo Different number of files)
If your system is not in english you have to change the "File" according with your system language (ie: "Fichier(s)' in French)
EDIT :
To compare more Directory with the FIRST ONE :
#echo off
set $Folder1="c:\Users\abc\INBOX"
set $folder2="c:\Users\abc\OUTBOX"
set $Folder3=c:\Users\abc\OUTBOX\PROC
set $Folder4=c:\Users\abc\OUTBOX\PEND
set $Count=0
setlocal EnableDelayedExpansion
for %%x in (%$Folder1% %$Folder2% %$Folder3% %$Folder4%) do (
for /f "tokens=1 delims= " %%a in ('dir %%x /a-d ^| find /i "File(s)"') do (
call:test %%x %%a
if !$count! Equ 0 set $Ref=%%a
set $Count=1))
exit/b
:test
if !$count! Equ 1 (
If "%$Ref%" Equ "%2" (echo %$Folder1% SAME %1) else (echo %$Folder1% DIFFERENT %1))

Resources