提取批处理文件的最后一个命令行参数

提取批处理文件的最后一个命令行参数

我必须修改一个批处理文件(由一位前员工编写),该文件使用循环for %%f in (%*) do ( ... )来操作每个命令行参数。新的要求是将目录名称附加到批处理调用中,并且此目录将用于每个参数,并带有相对路径。例如:

DoJob.bat Fin.txt "D:\Ref Quotes\\*.pdf" ..\\*.doc "E:\Jan 2012"

应翻译为:

DoJob.bat "E:\Jan 2012\Fin.txt" "D:\Ref Quotes\\*.pdf" "E:\Jan 2012\\..\\*.doc"

一旦我将最后一个命令行参数放入变量中,我就可以将其作为每个不包含冒号(因此是相对路径)的参数的前缀。但我的问题是,如何获取这个最后一个命令行参数,以及如何让上面的循环在倒数第二个参数处停止处理?

(请不要建议批处理文件的替代方案;我已经询问过了,唯一可用的选项是修改现有的文件。)

答案1

您可以使用 SHIFT 和循环遍历所有命令行参数。由于 SHIFT 会消耗每个参数,因此您需要在子程序中执行此操作。我在此处介绍的子程序还会计算参数,因此您知道稍后要循环遍历多少个参数。

@echo off

set argCount=0

call :GetLastArg %*

REM subtract 1 from arg count, so we know how many to process.
set /a argCount-=1

echo.
echo Arguments to Process: %argCount%
echo Last Argument: %lastArg%


echo.
echo Here are the other arguments:
echo.
:BeginArgProcessingLoop
if %argCount% == 0 goto EndArgProcessingLoop
set /a argCount-=1
echo %1
shift
goto BeginArgProcessingLoop
:EndArgProcessingLoop

goto :eof


REM This subroutine gets the last command-line argument by
REM using SHIFT. It also counts the number of arguments.
:GetLastArg
set /a argCount+=1
set "lastArg=%~1"
shift
if not "%~1"=="" goto GetLastArg
goto :eof

因为我们使用 SHIFT,所以这个过程与您原来的命令行一起工作......

batch.cmd fin.txt "D:\Ref Quotes\*.pdf" ..\*.doc "E:\Jan 2012"

Arguments to Process: 3
Last Argument: E:\Jan 2012

Here are the other arguments:

fin.txt
"D:\Ref Quotes\*.pdf"
..\*.doc

以及数量大于 9 的参数列表,如果您使用 %1 到 %9 则会导致问题……

batch.cmd fin.txt "D:\Ref Quotes\*.pdf" ..\*.doc manifesto.txt
87.docx "C:\Plans to Rule Earth\*.ppt" "Compromising Photos\*.jpg" "What's Up.do
c" "Gimme All Your Lovin'.mp3" out-of-funny-ideas.xls "E:\Jan 2012"

Arguments to Process: 10
Last Argument: E:\Jan 2012

Here are the other arguments:

fin.txt
"D:\Ref Quotes\*.pdf"
..\*.doc
manifesto.txt
87.docx
"C:\Plans to Rule Earth\*.ppt"
"Compromising Photos\*.jpg"
"What's Up.doc"
"Gimme All Your Lovin'.mp3"
out-of-funny-ideas.xls

答案2

除了使用 Shift 之外,我们还可以一举两得,我们可以使用 sort 来反转参数的顺序并将它们保存在变量中,然后抓住第一个参数用于你的目的,然后将其从变量中删除并提交给你的原始代码。

或者,甚至更简单,只需利用这样一个事实:在设置变量的循环中,该变量将等于最后设置的值)

*如果目录路径中有空格,请记得用引号括起来

例如

 @( SetLocal EnableDelayedExpansion
    Echo Off
    REM  Capture arguments to variable
    SET "_Args=%*"
 )

 REM Get Directory to use that is the last term:
 For %%A IN (%*) DO ( SET "_DirectoryPath=%%A")

 REM Remove directory from _Args variable:
 SET "_Args=!_Args:%_DirectoryPath%=!"

 REM Now for your original script use !_Args! Instead of %*

 For %%f in (!_Args!) do ( ... ) 

相关内容