关于windows:如何从第N个位置获取批处理文件参数?

how to get batch file parameters from Nth position on?

关于如何在批处理文件中传递命令行参数,如何准确地指定其余参数来获取这些参数?我不想使用shift,因为我不知道可能有多少参数,如果可以的话,我想避免计算这些参数。

例如,给定此批处理文件:

1
2
3
4
5
6
7
8
9
10
@echo off
set par1=%1
set par2=%2
set par3=%3
set therest=%???
echo the script is %0
echo Parameter 1 is %par1%
echo Parameter 2 is %par2%
echo Parameter 3 is %par3%
echo and the rest are %therest%

运行mybatch opt1 opt2 opt3 opt4 opt5 ...opt20将产生:

1
2
3
4
5
the script is mybatch
Parameter 1 is opt1
Parameter 2 is opt2
Parameter 3 is opt3
and the rest are opt4 opt5 ...opt20

我知道%*给出了所有参数,但我不想给出前三个参数(例如)。


以下是不使用SHIFT的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@echo off

for /f"tokens=1-3*" %%a in ("%*") do (
    set par1=%%a
    set par2=%%b
    set par3=%%c
    set therest=%%d
)

echo the script is %0
echo Parameter 1 is %par1%
echo Parameter 2 is %par2%
echo Parameter 3 is %par3%
echo and the rest are %therest%


1
2
3
4
5
6
7
8
9
10
11
@echo off
setlocal enabledelayedexpansion

set therest=;;;;;%*
set therest=!therest:;;;;;%1 %2 %3 =!

echo the script is %0
echo Parameter 1 is %1
echo Parameter 2 is %2
echo Parameter 3 is %3
echo and the rest are: %therest%

这适用于带引号的参数和具有等号或逗号的参数,只要前三个参数没有这些特殊的分隔符字符。

样品输出:

1
2
3
4
5
test_args.bat"1 1 1" 2 3 --a=b"x y z"
Parameter 1 is"1 1 1"
Parameter 2 is 2
Parameter 3 is 3
and the rest are: --a=b"x y z"

这是通过替换原始命令行%*中的%1 %2 %3来实现的。前五个分号的存在只是为了确保这些%1 %2 %3的第一个出现被替换。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@ECHO OFF
SET REST=
::# Guess you want 3rd and on.
CALL :SUBPUSH 3 %*
::# ':~1' here is merely to drop leading space.
ECHO REST=%REST:~1%
GOTO :EOF

:SUBPUSH
SET /A LAST=%1-1
SHIFT
::# Let's throw the first two away.
FOR /L %%z in (1,1,%LAST%) do (
  SHIFT
)
:aloop
SET PAR=%~1
IF"x%PAR%" =="x" (
  GOTO :EOF
)
ECHO PAR=%PAR%
SET REST=%REST%"%PAR%"
SHIFT
GOTO aloop
GOTO :EOF

我喜欢用子程序代替EnableDelayedExpansion。上面是从我的dir/file模式处理批中提取的。不要说这不能处理=的参数,但至少可以使用空格和通配符来处理带引号的路径。


下面的代码使用SHIFT,但是它避免了使用for解析命令行,并且让命令行解释器完成这项工作(考虑到for没有正确解析双引号,例如,A B""CA解释为3个参数,B""Cfor解释为3个参数,but作为解释程序的2个参数AB""C;这种行为防止引用的路径参数(如"C:\Program Files\")被正确处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@echo off

set"par1=%1" & shift /1
set"par2=%1" & shift /1
set"par3=%1" & shift /1

set therest=
set delim=

:REPEAT
if"%1"=="" goto :UNTIL
set"therest=%therest%%delim%%1"
set"delim="
shift /1
goto :REPEAT
:UNTIL

echo the script is"%0"
echo Parameter 1 is"%par1%"
echo Parameter 2 is"%par2%"
echo Parameter 3 is"%par3%"
echo and the rest are"%therest%"
rem.the additional double-quotes in the above echoes^
    are intended to visualise potential whitespaces

%therest%中的其余参数可能不像最初那样涉及分隔符(请记住,命令行解释器也将制表符、,;=视为分隔符以及所有组合),因为这里所有分隔符都被一个空格替换。但是,当把%therest%传递给其他命令或批处理文件时,它将被正确地解析。

到目前为止,我遇到的唯一限制适用于包含插入符号字符^的参数。其他限制(与<>|&"有关)适用于命令行解释器本身。