batch for loop increment value ENABLEDELAYEDEXPANSION - batch-file

I'm trying to make a simple batch-file to make 7zip-archives from all the files in it's directory.
I want the 7zip-archives to get names like a01.7z, a02.7z, a03.7z...
Apparently incrementing a value in a batch-for-loops isn't easy.
The setlocal ENABLEDELAYEDEXPANSION solution doesn't work on my computer (windows 10, 64-bit)
Someone suggested putting the increment-code in a subroutine:
set /a counter=0
for %%i in (*.*) do (
call :pass2
goto :cont
:pass2
set /a counter=%counter%+1
goto :EOF
:cont
"c:\Program Files\7-Zip\7z.exe" a a%counter% "%%i"
)
This doesn't work because somehow DOS doesn't understand the final "%%i" anymore and just outputs "%i".
Please teach me how to make a for-loop in batch with a counter.

This is the simplest way to generate two-digits numbers, with a left zero:
#echo off
setlocal EnableDelayedExpansion
set /A counter=100
for %%i in (*.*) do (
set /A counter+=1
"c:\Program Files\7-Zip\7z.exe" a a!counter:~1! "%%i"
)

setlocal enabledelayedexpansion
set /a counter=0
for %%i in (*.*) do (
set /a counter=!counter!+1
#echo "c:\Program Files\7-Zip\7z.exe" a a!counter! "%%i"
)
This adds 1 file per zip.

Related

Use a "for" to include different file extensions

This is the whole script but I'm just interested in modifying the following line:
for /R %%x in (*.jpg)
I want to include also *.png and *.gif
setlocal enabledelayedexpansion enableextensions
set PATH=%PATH%;C:\"Program Files"\FileOptimizer
Set /A "threads=8,i=0"
:: initialize List
For /L %%n in (1,1,%threads%) Do Set "List%%n="
for /R %%x in (*.jpg) do (
Set /A "n=i %% threads + 1,i+=1"
call set "LIST!n!=%%LIST!n!%% "%%x""
)
For /L %%n in (1,1,%threads%) Do (
echo list: !LIST%%n!
START FileOptimizer64.exe !LIST%%n!
)
for /R %%x in (*.jpg,*.png,*.gif)
That's it.

Checking if an array element(file) has a specific extension

I'm trying to write a code that does the following. I have some files in a directory with specific extensions. I have made a vector that contains all of them. Now I will want to rename each file to something else depending on their extension. So for that I'm trying to parce the created vector with a for loop in which I check for each element extension.
For now I won't rename it just echo it on the screen if the file with the .elf extension is found. I wrote this code but I get no echo as in there would be no .elf file in my directory. Please help me correct this. Thanks.
#echo off
setlocal enabledelayedexpansion
cd C:\Users\uidr0938\Desktop\Copy
set path=C:\Users\uidr0938\Desktop\Copy
set /a index=0
for /r %%i in (*) do (
set value[!index!]=%%i
set /a index+=1
)
set /a limit=%index%-2
for /l %%a in (0;1;%limit%) do (
if !value[%%a]! equ *.elf (
echo !value[%%a]!
)
)
endlocal
try with :
....
for /l %%a in (0;1;%limit%) do (
if "!value[%%a]:~-4!" equ ".elf" (
echo !value[%%a]!
)
)
when comparing string you cannot use wildcards.Here you can see some examples about batch substrings
Here is a slightly different way of doing it.
#IF NOT EXIST "%USERPROFILE%\Desktop\Copy\" #EXIT/B
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "_path=%USERPROFILE%\Desktop\Copy"
SET "_index=0"
FOR /F "DELIMS=" %%A IN ('WHERE/R "%_path%" * 2^>NUL') DO (SET/A "_index+=1"
SET "_value[!_index!]=%%A")
IF %_index% EQU 0 EXIT/B
FOR /F "TOKENS=1* DELIMS==" %%A IN ('SET _value['
) DO IF /I "%%~xB"==".elf" ECHO %%B
PAUSE

Batch file to rename file and add sequence number to the file name

I picked up the code below from another post. I believe it should pick up the current directory folder and include it in the renaming part of the process, however that doesn't seem to work for me.
#ECHO OFF
setlocal enabledelayedexpansion
PUSHD "%~1"
set inc=0
FOR /f "delims=" %%a in ('dir /b /a-d') DO (
set /a inc+=1
Echo Ren: "%%a" "%~n1!inc!%%~xa"
Ren "%%a" "%~n1!inc!%%~xa"
)
POPD
I have a .txt file that will be received into a folder each day named and time stamped. Example as below:
FileNameA_20170418153000.txt
Essentially I'd like to amend the code above to rename the file: filenam0001.txt and continue to update the sequence number (which works perfectly well).
i.e.
filenam0001.txt
filenam0002.txt
filenam0003.txt
Any help would be greatly appreciated.
you need to add the leading zeros manually (add some zeros, then cut the last x characters):
#echo off
setlocal EnableDelayedExpansion
set inc=0
for /l %%a in (1,1,50) do (
set /a inc+=1
set num=00000000!inc!
set num=!num:~-5!
echo !num!
)
I modified your code in order to insert the leading zeros in a simple way...
#ECHO OFF
setlocal enabledelayedexpansion
PUSHD "%~1"
set inc=10000
FOR /f "delims=" %%a in ('dir /b /a-d') DO (
set /a inc+=1
Echo Ren: "%%a" "%~n1_%%~na!inc:~1!%%~xa"
Ren "%%a" "%~n1_%%~na!inc:~1!%%~xa"
)
POPD

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.

The syntax of the command is incorrect : for loop batch

I'm making a batch script to stop several services , however i get the syntax is incorrect error at second FOR which loops in serviceList.TEMP
setlocal EnableDelayedExpansion
setlocal enableExtensions
::queryex output file
sc queryex>services.TEMP
find /i /N "DISPLAY_NAME: Hotspot" services.TEMP>tmp1.TEMP
FOR /F "skip=2" %%G in (tmp1.TEMP) do (
set num=%%G
set num=!num:~1,3!
echo !num!>serviceList.TEMP
)
FOR %%X in (serviceList.TEMP) do (
set /a "SKIP_LINES=%%G+7"
set secondForFilter="skip=%SKIP_LINES%"
FOR /F %secondForFilter% %%Z in (services.TEMP) do (
call debug.cmd REM debug.cmd -> echo debug pause>nul
set serv=%%Z
set "serv=!serv: =!" REM Extract PID
set "serv=!serv::=!" REM Extract PID
set procID=!serv!
taskkill /pid %procID% /f >>debug.txt 2>>debug.txt
goto secondLoopEnd
)
:secondLoopEnd
)
del /S *.TEMP >>debug.txt 2>>debug.txt
the problem is here:
FOR %%X in (serviceList.TEMP) do (
set /a "SKIP_LINES=%%G+7"
set secondForFilter="skip=%SKIP_LINES%"
FOR /F %secondForFilter% %%Z in (services.TEMP) do (
call debug.cmd REM debug.cmd -> echo debug pause>nul
the usual approach when you set value in brackets context is to use delayed expansion but it wont work for parametrized for options.
Here you'll need a subroutine.
And you have GOTO in the for loop. GOTO breaks for context and the loops will be not called after goto is executed.
And rem cannot be used on the same line as the code without "&"
Consider something like this (though I cannot check the logic of the bat):
setlocal EnableDelayedExpansion
setlocal enableExtensions
::queryex output file
sc queryex>services.TEMP
find /i /N "DISPLAY_NAME: Hotspot" services.TEMP>tmp1.TEMP
FOR /F "skip=2" %%G in (tmp1.TEMP) do (
set num=%%G
set num=!num:~1,3!
echo !num!>serviceList.TEMP
)
FOR %%X in (serviceList.TEMP) do (
call :subroutine %%G
)
del /S *.TEMP >>debug.txt 2>>debug.txt
exit /b %errorlevel%
:subroutine
setlocal enableDelayedExpansion
set /a skiplines=%~1+7
set "filter="skip=%skiplines%""
FOR /F %filter% %%Z in (services.TEMP) do (
call debug.cmd
set serv=%%Z
rem extract PID
set "serv=!serv: =!"
set "serv=!serv::=!"
set procID=!serv!
taskkill /pid !procID! /f >>debug.txt 2>>debug.txt
goto :break_for
)
:break_for
endlocal
exit /b
Should the > in your echo to serviceList.TEMP be a >> so that you append to the file?
echo !num!>>serviceList.TEMP
In which case, you should also ensure that the file is deleted prior to the appending operations.
Also, I assume you missed the /F from your FOR loop, as you're trying to read the lines of the serviceList.TEMP file, yes?
FOR %%X in (serviceList.TEMP) do (
Should be...
FOR /F %%X in (serviceList.TEMP) do (
?
Also, you can append to the same file with both std out and err by doing this...
someprocesshere 1> out.log 2>&1

Resources