I would like to write a dos batch file to test a program several times
on different files.
I'v got something like this
prog.exe file.in > file.out
So i need to apply prog.exe to each file of my directory. I've got the
names of all the files (file.in) and I apply my prog to each one, and
I would like to construct the name of file.out using the name of
file.in and changing the extension.
So how can I do it ?
Thanks for answers.
Hilaire VERSCHUERE
Try something along these lines. The generated command
is ECHOed as a demo. Remove the ECHO.{demo!} and the
"quotes" around the command to activate it.
====Begin cut-and-paste (omit this line)
@ECHO OFF
IF (GOTO:)==(%1) %1%2 {Subroutine-Handler}
FOR %%F IN (*.IN) DO CALL %0 GOTO: _FSCAN %%F
GOTO EOF {=Subroutine-section-below=}
:_FSCAN (Usage: CALL %0 GOTO: _FSCAN FileSpec)
SET V=
:: Copy file to %V% extension
COPY %3 *.%%V%%>NUL
:: Grab base name of file in variable FN
FOR %%F IN (*.%%V%%) DO ECHO.SET FN=%%F>%TEMP%.\_FN.BAT
FOR %%C IN (CALL DEL) DO %%C %TEMP%.\_FN.BAT
:: Remove ECHO.{demo!} and "quotes" to activate command
ECHO.{demo!}" program.exe %3 > %FN%OUT "
SET FN=
:EOF {End-of-file}
====End cut-and-paste (omit this line)
Win9x GUI study/demo only. Cut-and-paste as Batch script (file with .BAT
extension). Lines that don't begin with 2 spaces have wrapped by mistake.
This screen capture shows operation. Remove the
ECHO.{demo!} and the "quotes" around the demo
command line in the above script to activate it.
============Screen capture Windows 95
C:\WORK>dir /b *.in
FILE1.IN
FILE2.IN
FILE3.IN
FILE4.IN
C:\WORK>demo.bat
{demo!}" program.exe FILE1.IN > FILE4.OUT "
{demo!}" program.exe FILE2.IN > FILE4.OUT "
{demo!}" program.exe FILE3.IN > FILE4.OUT "
{demo!}" program.exe FILE4.IN > FILE4.OUT "
C:\WORK>
============End screen capture
--
William and Linda Allen
Learn to write Batch Files on your Win95/98/ME PC. Free, interactive
Web Course. Syllabus and Index to Lessons: http://www.allenware.com/
This revised version adds the missing DEL command needed
to remove the transient workfiles:
====Begin cut-and-paste (omit this line)
@ECHO OFF
IF (GOTO:)==(%1) %1%2 {Subroutine-Handler}
FOR %%F IN (*.IN) DO CALL %0 GOTO: _FSCAN %%F
GOTO EOF {=Subroutine-section-below=}
:_FSCAN (Usage: CALL %0 GOTO: _FSCAN FileSpec)
SET V=
:: Copy file to %V% extension
COPY %3 *.%%V%%>NUL
:: Grab base name of file in variable FN
FOR %%F IN (*.%%V%%) DO ECHO.SET FN=%%F>%TEMP%.\_FN.BAT
DEL *.%%V%%
FOR %%C IN (CALL DEL) DO %%C %TEMP%.\_FN.BAT
:: Remove ECHO.{demo!} and "quotes" to activate command
ECHO.{demo!}" program.exe %3 > %FN%OUT "
SET FN=
:EOF {End-of-file}
====End cut-and-paste (omit this line)
Win9x GUI study/demo only. Cut-and-paste as Batch script (file with .BAT
extension). Lines that don't begin with 2 spaces have wrapped by mistake.
--
So I wrote it and don't understand why it doesn't work :
FOR %%A IN (*.IN) DO (
Set outFile=%%A
Set outFile=%outFile:.IN=.OUT%
prog.exe %%A > outFile
)
whereas this work :
------------------------
Set outFile=file.in
Set outFile=%outFile:.in=.out%
Echo %outFile%
------------------------
Result:
file.out
I think I made a confusion between var and string but I don't know how
to solve it. So, is there any solution ?
Hilaire VERSCHUERE
The posted Batch demo was for Windows 95/98/ME
> So I wrote it and don't understand why it doesn't work :
>
> FOR %%A IN (*.IN) DO (
> Set outFile=%%A
> Set outFile=%outFile:.IN=.OUT%
> prog.exe %%A > outFile
> )
We don't use Windows 2000/XP (but you are clearly using Windows
2000/XP or similar). You need to understand about delayed Environment
variable expansion to set _and_then_use_ variables within the scope of
FOR IN DO (parentheses). And in any event your line:
prog.exe %%A > outFile
is wrong since you don't expand the outFile variable as %outFile% (but
don't bother, it won't work, you need delayed variable expansion ON and
to use the delayed variable expansion operator ! anyway).
To rewrite your code with delayed variable expansion, read the help under
cmd /?
Alternatively, I think it's generally better to adopt a Subroutine
coding technique, as in this variant of your code, where each
instantiation of the metavariable %%A is passed to a Subroutine
at :FSCAN where the variable will be seen as the %1 parameter
====Begin cut-and-paste (omit this line)
@ECHO OFF
FOR %%A IN (*.IN) DO CALL :FSCAN %%A
GOTO :EOF
:FSCAN
Set outFile=%1
Set outFile=%outFile:.IN=.OUT%
ECHO.{demo!}" prog.exe %1>%outFile% "
====End cut-and-paste (omit this line)
Win2000 simulated study/demo only. Cut-and-paste as Batch script.
Lines that don't begin with 2 spaces have wrapped by mistake.
Remove the ECHO.{demo!} and the "quotes" to activate the command.
If you think that some file names may have embedded [Space]s,
you should "quote" the second instance of "%%A" in the FOR IN
DO line to pass it properly.
============Screen capture Windows 2000 simulated in Win95
C:\WRK2>dir *.in /b
FILE1.IN
FILE2.IN
FILE3.IN
C:\WRK2>demo
{demo}" prog.exe FILE1.IN>FILE1.OUT "
{demo}" prog.exe FILE2.IN>FILE2.OUT "
{demo}" prog.exe FILE3.IN>FILE3.OUT "
C:\WRK2>
============End screen capture
I tried with a subroutine as you explained and it works perfectly :)
Thanks for all.