batch script - write all files found in one directory into one command line?

两盒软妹~` 提交于 2021-02-10 15:00:26

问题


I have a directory with a bunch of files with a mix of extension. I only want to work with files with extension *.abc. Each *.abc file should then be handed over to another software with some parameters. The parameters are always the same for each file. One of the parameters needs to be defined by the user, though.

So my first try was this:

@ECHO OFF
set /p value="Enter required imput value: "
for %%f in (*.abc) do (
START C:\"Program Files"\Software\startsoftware.exe -parameter1 "%%~nf.abc" -parameter2 %value% -parameter3
)
PAUSE

The script works but is causing a memory crash, as the software is getting all request basically at once. However, if I could manage to write all file names in one command line the software would process all files one by one. It needs to be called like this:

START C:\"Program Files"\Software\startsoftware.exe -parameter1 file1.abc -parameter2 %value% -parameter3 -parameter1 file2.abc -parameter2 %value% -parameter3 -parameter1 file3.abc -parameter2 %value% -parameter3 -parameter1 file4.abc -parameter2 %value% -parameter3

My idea was to generate a files.txt with listing all *.abc using

dir /b /a-d > files.txt

and then read that list into my command. However, I don't know how to read out the files.txt and apply parameters including the variable %value% to each file.


回答1:


1. Quote inside an argument string

" inside an argument string is usually not correct. The entire argument string must be usually enclosed in double quotes and not just parts of it. So wrong is C:\"Program Files"\Software\startsoftware.exe and correct would be "C:\Program Files\Software\startsoftware.exe".

That can be seen by opening a command prompt, typing C:\Prog and hitting key TAB to let Windows command processor complete the path to "C:\Program Files". The Windows command processor added automatically the required double quotes around entire path string. The path would change to "C:\Program Files (x86)" on pressing once more key TAB. However, continue typing with "C:\Program Files" displayed by entering \soft and press again TAB and displayed is "C:\Program Files\Software". The second " moved to end of new path. Type next \start and press once more TAB. Now is displayed "C:\Program Files\Software\startsoftware.exe" which is the correct full qualified file name of this executable enclosed in double quotes as required because of the space character in path.

For more information about this feature of Windows command processor run in command prompt window cmd /? and read the output help from top of first page to bottom of last page.

2. START and TITLE string

The help for command START is output on running start /? in a command prompt window.

START interprets the first double quoted string as optional title string for the console window. For that reason it is advisable to specify first after command name START always a title in double quotes. In case of a Windows GUI application is started on which no console window is opened at all or a console application is executed in background without opening a new console window, the title string can be specified with just "" after START which is just an empty title string.

3. Running applications parallel

The command START is used to run an application or script parallel to the Windows command process which is processing the batch file. This is often useful, but definitely not here on which an application should be executed to process a file of a large set of files which need to be processed all.

The following command line would start for each *.abc file the executable startsoftware.exe for execution parallel to cmd.exe which is processing the batch file.

for %%f in (*.abc) do START "" "C:\Program Files\Software\startsoftware.exe" -parameter1 "%%~nf.abc" -parameter2 %value% -parameter3

This results with many *.abc files in current directory in a situation on which Windows fails to run one more process due to a resource problem as too many processes are running already more or less parallel.

4. Running application in series

It is usually better on processing many files to run an application for processing a file and halt processing of the batch file until the application finished and terminated itself. That can be achieved by not using the command START.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
if not exist *.abc (
    echo ERROR: There are no *.abc in folder: "%CD%"
    echo/
    pause
    goto :EOF
)
set "Value="
:UserPrompt
set /P "Value=Enter required imput value: "
if not defined Value goto UserPrompt
set "Value=%Value:"=%"
if not defined Value goto UserPrompt
for %%I in (*.abc) do "C:\Program Files\Software\startsoftware.exe" -parameter1 "%%I" -parameter2 "%Value%" -parameter3
endlocal

The behavior on starting an executable from within a batch file is different to doing that from within a command prompt window. The Windows command processor waits for the self-termination of the started executable on being started during processing of a batch file. Therefore this code runs always just one instance of startsoftware.exe in comparison to the loop above using command START to start multiple instances quickly in a short time.

5. Running application with multiple files

It looks like it is possible to run startsoftware.exe with multiple arguments to process several files at once. But the maximum command line length limit of 8191 characters must be taken into account on writing a batch file which runs the executable with a list of arguments to process multiple files at once.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
if not exist *.abc (
    echo ERROR: There are no *.abc in folder: "%CD%"
    echo/
    pause
    goto :EOF
)
set "Value="
:UserPrompt
set /P "Value=Enter required imput value: "
if not defined Value goto UserPrompt
set "Value=%Value:"=%"
if not defined Value goto UserPrompt

set "Arguments="
set "CmdLineLimit="
for /F "eol=| delims=" %%I in ('dir *.abc /A-D /B 2^>nul') do call :AppendFile "%%I"
if defined Arguments "C:\Program Files\Software\startsoftware.exe"%Arguments%
goto :EOF

:AppendFile
set Arguments=%Arguments% -parameter1 %1 -parameter2 "%Value%" -parameter3
set "CmdLineLimit=%Arguments:~7800,1%"
if not defined CmdLineLimit goto :EOF
"C:\Program Files\Software\startsoftware.exe"%Arguments%
set "Arguments="
set "CmdLineLimit="
goto :EOF

The loop for %%f in (*.abc) do is modified in this code to a for /F loop to get first a list of file names loaded completely into memory instead of processing the directory entries which could change on each execution of startsoftware.exe if it modifies the *.abc files in current directory.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • dir /?
  • echo /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • set /?
  • setlocal /?

See also Where does GOTO :EOF return to?



来源:https://stackoverflow.com/questions/62352544/batch-script-write-all-files-found-in-one-directory-into-one-command-line

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