问题
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