for loop with counter

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

for loop with counter

Post by MigrationUser »

26 Apr 2015 16:00
shayo19

Hello
I need to apartial file list (5files) so i wrote the following:

Code: Select all

Set cnt=1
For /f "tokens=*" %%a in ('dir /b') echo %%a>>list.txt && set /a cnt+=1 && if %cnt%==5 goto end
:End
When i run the batch the cnt always stays 1 so that the list is the whole files in the directory.

Can you please help the goal is to create list of the first 5 files in the directory.

Thanks.

----------------------------

#2 26 Apr 2015 20:12
foxidrive

Without knowing the actual task nobody can give you the most appropriate solution - but this gets the first 5 filenames:

Code: Select all

@echo off
(for /f "tokens=1,2 delims=:" %%a in ('dir /b /a-d ^|findstr /n "."^|findstr "^[1-5]"') do echo %%b)>list.txt
Last edited by foxidrive (26 Apr 2015 20:13)

----------------------------

#3 26 Apr 2015 20:38
shayo19

Hi foxidrive thanks for answering.
The task is abit more complicated ill try to explain.
Im working with bmp images and i need to create batch that "stiching" every 5 pic to panorama image using irfanview program. The syntax is iview.exe /panorama=(1,pic1,pic2...) /convert=set1-5.bmp and so on.
The value 1 before the pic is for horizontal order and the convert switch is in order to save the output image.
so im trying to find away that the batch will loop and fill 5 pictures to the command and will create panorama for every set of 5 pictures that exist in the directory until that he cant find 5 pic to process.
If you can help me I'll apriciate alot.
Thanks in advance.

----------------------------

#4 27 Apr 2015 11:54
foxidrive

I have a script but irfanview has a bug and does not support double quoted names within the /panorama command.

Try this, and then try the one below it - which works. I tested with JPG but BMP should be the same.
Because of this problem, specifying full paths and any poison characters will break the command.

iview /panorama=(1,"a c.jpg","b.jpg") /convert="set-33.jpg"

iview /panorama=(1,a c.jpg,b.jpg) /convert="set-33.jpg"

----------------------------

#5 27 Apr 2015 12:32
foxidrive

There is a workaround - test this in a folder of copies of your test files.
You asked to only process sets of 5 images so any leftover files will not be processed.

Check the path to irfanview also.

Code: Select all

@echo off
setlocal enabledelayedexpansion

set numfiles=5
set "iv=c:\Program Files\Irfanview\iview.exe"

set c=0
set number=100000
set "tempfolder=%cd%\temp-pano-001"
for /f "delims=" %%a in ('dir *.bmp /b /a-d') do (
rd "%tempfolder%" 2>nul
md "%tempfolder%" 2>nul
   set /a c+=1
   move "%%~fa" "%tempfolder%" >nul 
   set /a check=c %% %numfiles%
     if !check! EQU 0 (
       pushd "%tempfolder%"
        set /a number+=1
        echo "%userprofile%\desktop\Infanview Panoramas\set-!number:~-4!%%~xa"
        "%iv%" /panorama=(1,*^) /convert="%userprofile%\desktop\Infanview Panoramas\set-!number:~-4!%%~xa"
        move * .. >nul
        set c=0
        popd
      )
)
if exist "%tempfolder%\*" for %%a in ("%tempfolder%\*") do move "%%~a" . >nul
rd "%tempfolder%" 2>nul

pause
----------------------------

#6 27 Apr 2015 21:05
Shadow Thief
shayo19 wrote:

Hello
I need to apartial file list (5files) so i wrote the following:

Code: Select all

    Set cnt=1
    For /f "tokens=*" %%a in ('dir /b') echo %%a>>list.txt && set /a cnt+=1 && if %cnt%==5 goto end
    :End
When i run the batch the cnt always stays 1 so that the list is the whole files in the directory.

Can you please help the goal is to create list of the first 5 files in the directory.

Thanks.
This is a classic example of not using delayed expansion. Also, it never hurts to have a multiline for loop, but that's just personal preference.

Code: Select all

@echo off
setlocal enabledelayedexpansion
Set cnt=1
For /f "tokens=*" %%a in ('dir /b') do (
    echo %%a>>list.txt
    set /a cnt+=1
    if !cnt!==5 goto end
)
:End
Last edited by Shadow Thief (27 Apr 2015 21:06)

----------------------------

#7 27 Apr 2015 21:45
dbenham

foxidrive asked if I could see a way to use one of my hybrid JScript/batch utilities to conveniently solve this problem without using delayed expansion.

I've come up with the following, which uses my JREPL.BAT utility.

I pipe DIR /B to JREPL first to add a \n (without \r) after each group of 5 files.
A second pipe to JREPL replaces \r\n with nothing or comma so as to get an appropriately formatted comma delimited list of 5 files per line.
The last pipe to FINDSTR simply numbers each line.
The final result is iterated and parsed by FOR /F

This solution assumes there are no commas in any of your file names. I don't have IrfanView, so obviously it hasn't been tested.
EDIT - fixed a couple silly bugs

Code: Select all

@echo off
setlocal
set imageCount=5
set "outpath=c:\yourOutputFolder"
pushd "c:\yourSourceFolder"
for /f "tokens=1,2 delims=:" %%A in (
  'dir /b^|jrepl "(.+\n){%imageCount%}" "$0+'\n'" /m /jmatch /x^|jrepl "^\r\n:\r\n(?=.):\r\n" ":,:" /m /t ":"^|findstr /n "^"'
) do iview /panorama=(1,%%B) /convert="%outpath%\set-%%A.bmp"

Dave Benham

Last edited by dbenham (29 Apr 2015 16:35)

----------------------------

#8 29 Apr 2015 15:46
foxidrive


Dave, thanks for your input here, though your solution has the same problem I described.

IV has a flaw where a comma delimited string can't be used due to poison characters such as & too.
foxidrive wrote:

I have a script but irfanview has a bug and does not support double quoted names within the /panorama command.


I was looking to get batches of 5 files into a temp folder, run the command using the wildcard mode, move them back - rinse and repeat.
...but pad the output filename with leading zeros too, without using delayed expansion and convoluted plain-batch coding.

Last edited by foxidrive (29 Apr 2015 16:03)

----------------------------

#9 29 Apr 2015 16:32
dbenham


It is not hard to adapt my solution to your temp folder idea.

Code: Select all

@echo off
setlocal
set imageCount=5
set "outpath=c:\yourOutputFolder"
set "inpath=c:\yourInputFolder"
set "filemask=*"

pushd "%inpath%"
md panorama_temp 2>nul
cd panorama_temp || exit /b
del /q * 2>nul
for /f "tokens=1,2 delims=:" %%A in (
  'dir /b "..\%filemask%"^|jrepl "(.+\n){%imageCount%}" "$0+'\n'" /m /jmatch /x^|jrepl "^\r\n:\r\n(?=.):\r\n" ":\q,\q:\q" /m /x /t ":"^|findstr /n "^"'
) do (
  for %%F in (^"%%B) do move ..\%%F . >nul
  iview /panorama=(1,*^) /convert="%outpath%\set-%%A.bmp"
  move * .. >nul
)
cd ..
rd panorama_temp
popd

Dave Benham

Last edited by dbenham (29 Apr 2015 16:43)

----------------------------

#10 29 Apr 2015 17:20
dbenham


It is also possible to prepare the dir listing with a single JREPL call if you use more custum JScript:

Code: Select all

@echo off
setlocal
set imageCount=5
set "outpath=c:\yourOutputFolder"
set "inpath=c:\yourInputFolder"
set "filemask=*"

pushd "%inpath%"
md panorama_temp 2>nul
cd panorama_temp || exit /b
del /q * 2>nul
for /f "tokens=1,2 delims=:" %%A in (
  'dir /b "..\%filemask%"^|jrepl "^.*" "str+='\x22'+$0+'\x22,';if (ln%%5==0) {stdout.WriteLine(''+ln/5+':'+str);str=''};false" /jmatch /jbeg "var str=''"'
) do (
  for %%F in (%%B) do move ..\%%F . >nul
  iview /panorama=(1,*^) /convert="%outpath%\set-%%A.bmp"
  move * .. >nul
)
cd ..
rd panorama_temp
popd
Dave Benham

Last edited by dbenham (30 Apr 2015 12:25)

----------------------------

#11 30 Apr 2015 11:32
foxidrive
dbenham wrote:

It is also possible to prepare the dir listing with a single JREPL call if you use more custum JScript:

echo iview /panorama=(1,*^) /convert="%outpath%\set-%%A.bmp"

Dave Benham
That echo didn't output anything here.

Code: Select all

@echo off
setlocal
set imageCount=5
set "outpath=c:\yourOutputFolder"
set "inpath=d:\zzz & xxx"
set "filemask=*.jpg"

pushd "%inpath%"
md panorama_temp 2>nul
cd panorama_temp || exit /b
del /q * 2>nul
for /f "tokens=1,2 delims=:" %%A in (
  'dir /b "..\%filemask%"^|jrepl "^.*" "str+='\x22'+$0+'\x22,';if (ln%5==0) {stdout.WriteLine(''+ln/5+':'+str);str=''};false" /jmatch /jbeg "var str=''"'
) do (
  for %%F in (%%B) do move ..\%%F . >nul
  echo iview /panorama=(1,*^) /convert="%outpath%\set-%%A.bmp"
  move * .. >nul
)
cd ..
rd panorama_temp
popd
pause

The OP seems to have gone on holiday though.

d:\zzz & xxx\ketchup-holder-cup-unroll-unfold-the-rim.jpg
d:\zzz & xxx\life- & hacks-how-to-make-your-life-easier-1.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-10.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-11.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-12.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-14.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-15.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-16.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-17.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-18.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-19.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-2.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-20.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-21.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-22.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-23.jpg
d:\zzz & xxx\life-hacks-how-to-make-your-life-easier-24.jpg

----------------------------

#12 30 Apr 2015 12:30
dbenham

Oops - I forgot to double the percent in if (ln%5==0). I've edited my prior post to fix it.
Post Reply