在CMD批处理脚本中调用标签时,如何使用9个以上的参数?

Mec*_*ash 23 windows batch-file command-line-arguments

我想知道在调用标签时如何在批处理脚本中调用9个以上的参数.例如,以下显示我分配了12个参数,并尝试回显所有这些参数.

CALL:LABEL "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve"
PAUSE
GOTO:EOF


:LABEL
echo %1
echo %2
echo %3
echo %4
echo %5
echo %6
echo %7
echo %8
echo %9
echo %10
echo %11
echo %12
Run Code Online (Sandbox Code Playgroud)

%10%11和%12的输出最终为one0 one1 one2.我尝试过使用大括号,括号,引号,数字周围的单引号而没有任何运气.

kap*_*pex 26

如果要使用更多9个参数,请使用该shift命令.
(如果计算%0参数,实际上超过10个参数)

您可以使用shift命令创建一个可以接受10个以上批处理参数的批处理文件.如果在命令行上指定了10个以上的参数,则在第10个(%9)之后出现的参数将一次一个地移动到%9.

您可以使用循环,在移位之前存储变量,也可以像这样快速执行:

@echo off
CALL:LABEL "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve"
PAUSE
GOTO:EOF

:LABEL
:: print arguments 1-9
echo %1
echo %2
echo %3
echo %4
echo %5
echo %6
echo %7
echo %8
echo %9

:: print arguments 10-11
shift
shift 
echo %8
echo %9

:: print argument 13
shift
echo %9
Run Code Online (Sandbox Code Playgroud)

如果您有许多参数,可以用循环替换shift命令.以下for循环执行shift九次,因此这%1将是第十个参数.

@for /L %%i in (0,1,8) do shift
Run Code Online (Sandbox Code Playgroud)


Has*_*own 11

如果对任何人有帮助的话,就把我的帽子扔到擂台上

\n\n\n\n
Set a=%1 & Set b=%2 & Set c=%3 & Set d=%4 & Set e=%5 & Set f=%6 & Set g=%7 & Set h=%8 & Set i=%9\nShift & Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift\nSet j=%1 & Set k=%2 & Set l=%3 & Set m=%4 & Set n=%5 & Set o=%6 & Set p=%7 & Set q=%8 & Set r=%9\nShift & Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift\nSet s=%1 & Set t=%2 & Set u=%3 & Set v=%4 & Set w=%5 & Set x=%6 & Set y=%7 & Set z=%8\n
Run Code Online (Sandbox Code Playgroud)\n\n

我只是将其放在将使用 >9 个参数的 or 子例程的顶部.bat,然后您可以使用%a%through%z%而不是%1不存在的%26。

\n\n

太丑了,本来我是一行 \xc3\xa0 la

\n\n
Set a=%1 & Shift & Set b=%1 & Shift &...\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样它就只在一行上,并很快隐藏在编辑器的边缘后面,但显然Shift要到下一个真正的行才会生效;所有变量都设置为第一个参数。

\n\n

如果您想知道为什么要这样做而不是循环,除非有人告诉我您可以创建一种映射或数组,否则我需要在单行命令中使用变量,而不是echo(或做任何事情)使用它们一次:

\n\n
::example; concatenate a bunch of files\nSet output=%1\nShift\n<insert above behemoth>\ntype %a% %b% %c% %d% %e% %f% 2>NUL > %output%\n
Run Code Online (Sandbox Code Playgroud)\n\n

该死,这在 bash 中容易多了

\n\n
cat ${@:2} > "$1"\n
Run Code Online (Sandbox Code Playgroud)\n

  • 唯一需要的微调是删除参数和与号之间的空格。就像 Set a=%1&amp; Set b=%2&amp; Set c=%3&amp; ... 否则,在替换时,值中会附加不需要的空格。 (2认同)

kkk*_*kkk 6

这是使用该shift命令的另一种方法.

请注意,在这种情况下,您可以使用可变数量的参数.

@ECHO OFF
CALL:LABEL "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve"
PAUSE
GOTO:EOF

:LABEL
echo %1
shift
if not [%1]==[] GOTO LABEL
Run Code Online (Sandbox Code Playgroud)


Sel*_*edy 6

假设我们在这里使用的是最新版本的CMD,我很震惊地发现没有人发布以下内容,这使得无需使用笨拙的shift命令即可轻松处理任意数量的参数:

rem test.bat
call :subr %*
exit /b

:subr
for %%A in (%*) do (
    echo %%A
)
exit /b
Run Code Online (Sandbox Code Playgroud)

您也可以直接在“ main”中执行相同的技术。

这样,您就不会在处理参数时就吃光了,并且不需要shift,这意味着如果您有复杂的调用选项,并且可以使脚本的逻辑正确,那么您可以始终不停地遍历参数列表一次。更简单。

显然,如果do不止一次循环,则会增加计算复杂性以换取易读性,但是Bash和CMD都没有真正为提高速度而构建(据我所知),因此尝试通过优化来进行优化没有任何意义假设n小于100左右,则一次设置所有内容。

一些示例输出:

C:\tmp>test.bat one two three four five six seven eight nine ten eleven
one
two
three
four
five
six
seven
eight
nine
ten
eleven
Run Code Online (Sandbox Code Playgroud)

编辑 -任何人都CALL不可能处理针对另一个列表的参数,并且部分工作被嵌套,使用中介程序将正在处理的当前参数传递到内部循环中很重要;这样做set intermediary=%%OUTER似乎只是将其设置intermediary为一个空字符串,所以这是下一个最简单的方法:

setlocal enabledelayedexpansion
rem ^ in my experience, it's always a good idea to set this if for-loops are involved
for /f %%L in (file.txt) do (
    call :inner %%L
)
exit /b

:inner
for %%A in (%*) do (
    if %%A EQU %~1 call dosomething.bat %~1        
)
exit /b
Run Code Online (Sandbox Code Playgroud)

编辑2-此外,如果出于任何原因要shift在此处将方法添加到混合中-可能通过尝试使用a shift然后使用传递除1st以外的所有参数到子例程来进行call :subroutine %*-请注意,该方法将不起作用,因为%*实际上依次为您提供所有原始参数,而不考虑您所做的任何转换。
真可惜,因为(我所知道的)没有一种本机语法可以将所有参数组合在某个参数之后,就像人们期望的%3*那样。