Batch to process files one by one

前提是你 提交于 2020-01-04 15:31:55

问题


I have a batch file to compress PNG files. When I drag and drop some files on batch, it starts to process all of them in the same time. And it becomes useless when I tried with hundreds of files (sure)

The main part is something like that (simplified)

START "" /W truepng.exe /out "%~n1_out1.png" %1
START "" /W pngwolf.exe --in="%~n1_out1.png" --out="%~n1_out2.png"

I think I must to solve the "%1" part. I'm trying to make batch to process files with 4-file blocks. Thinking of 2 different aproach, and both fine.

1. Will process the first 4 file, after continue with other 4

2. Or it will run maximum 4 "pngwolf.exe" instances in the same time (best option)

In my several tests, I started to try with a counter logic %1 %2 %3 %4 after %n... But even in that phase I stucked and couldn't create a counter system. No need to ask, sure I'm newbie on batch coding. But even to be a good designer, looks like I need to learn more on batch. Thanks for anyone will give a hand. Hope there is a simple solution that I can understand and adaptate.

All Bests


回答1:


@ECHO OFF
SETLOCAL
SET /a instances=4
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
::
:loop
SET "nextfile=%~1"
IF NOT DEFINED nextfile (
 ECHO all done
 DEL "%tempfile%a*" >NUL 2>NUL
 GOTO :eof
)

FOR /L %%a IN (1,1,%instances%) DO (
 IF NOT EXIST "%tempfile%a%%a" (
  >"%tempfile%a%%a" ECHO.
  START "Instance %%a" oneconversion "%~1" "%tempfile%a%%a" %%a
  SHIFT
  GOTO loop
 )
)
timeout /t 1 >NUL
GOTO loop

GOTO :EOF

Where oneconversion.bat is

@ECHO OFF
SETLOCAL
START "" /W truepng.exe /out "%~n1_out1.png" %1
START "" /W pngwolf.exe --in="%~n1_out1.png" --out="%~n1_out2.png"
DEL "%~2" >NUL 2>NUL
cls
exit

As a dummy to prove the principle, I used as oneconversion.bat

@ECHO OFF
SETLOCAL
TITLE Processing %~1
SET /a wait=%~3*6
timeout /t %wait%
DEL "%~2" >NUL 2>NUL
CLS
exit

which is why the third parameter is supplied - it's only there to make oneconversion.bat variable-length.

The operation is fairly simple: establish a dummy temporary file and assume that that filename + a number is available as a flag file.

for each available instance (set to 4 - could be virtually anything) check for the flagfile, if it's missing, create it and despatch the next conversion, passing the required filename and temfilename. When the conversion's done, kill off the tempfile.


Edit to be more communicative:

@ECHO OFF
SETLOCAL
SET /a instances=4
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
::
:loop
SET "nextfile=%~1"
IF NOT DEFINED nextfile (
 IF EXIST "%tempfile%a" DEL "%tempfile%a"&ECHO All jobs started&GOTO loop
 IF EXIST "%tempfile%a*" GOTO delay
 ECHO all done
 pause
 GOTO :eof
)

FOR /L %%a IN (1,1,%instances%) DO (
 IF NOT EXIST "%tempfile%a%%a" (
  >"%tempfile%a%%a" ECHO.
  START "Instance %%a" oneconversion "%~1" "%tempfile%a%%a" %%a
  SHIFT
  GOTO loop
 )
)
:delay
timeout /t 1 >NUL
GOTO loop

GOTO :EOF

Very small changes:

When nextfile is found to be not defined, then all parameters have been exhausted. Look for the tempfile "%tempfile%a" - this has no affxed instance number and was being arbirarily deleted. If it exists, delete it and show the message "all jobs started" - there will still be jobs running, but no more will be addded, and go back to the loop.

Next time no parameters are found, "%tempfile%a" will not exist, so see whether any "%tempfile%a*" exists - which will indicate the subsidiary batch isn't finished. If such a file exists, go to delay to wait a second and try again.

When all of the jobs have finished, echo all done and pause to allow the message to be read.

Naturally, if you insert a control-g character into a displayed message, there will be a beep sounded if you want an audio alert.




回答2:


The variable that contains all parameters passed into the script is %*

You can process one at a time by using a for loop:

for %%A in (%*) do (
    START "" /W truepng.exe /out "%%~nA_out1.png" %%%A
    START "" /W pngwolf.exe --in="%%~nA_out1.png" --out="%%~nA_out2.png"
)


To process batches of four simultaneously, run all four instances of truepng first, and then all four instances of pngwolf.
:: Process four sets of truepng at once
start "" truepng.exe /out "%~n1_out1.png" %1
start "" truepng.exe /out "%~n2_out1.png" %2
start "" truepng.exe /out "%~n3_out1.png" %3
start "" truepng.exe /out "%~n4_out1.png" %4

:: Wait for 1 second/let the above commands catch up
ping -n 1 1.1.1.1>nul

:: Process four sets of pngwolf at once
start "" pngwolf.exe --in="%~1_out1.png" --out="%~n1_out2.png"
start "" pngwolf.exe --in="%~2_out1.png" --out="%~n2_out2.png"
start "" pngwolf.exe --in="%~3_out1.png" --out="%~n3_out2.png"
start "" pngwolf.exe --in="%~4_out1.png" --out="%~n4_out2.png"


来源:https://stackoverflow.com/questions/28521879/batch-to-process-files-one-by-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!