在 CMD 批处理脚本中调用标签时如何使用超过 9 个参数?

Posted

技术标签:

【中文标题】在 CMD 批处理脚本中调用标签时如何使用超过 9 个参数?【英文标题】:How do you utilize more than 9 arguments when calling a label in a CMD batch-script? 【发布时间】:2012-01-09 19:55:32 【问题描述】:

我想知道在调用标签时如何在批处理脚本中调用超过 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

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

【问题讨论】:

我想补充一点,SHIFT 允许将/N 开关与它结合使用,以选择从哪个参数开始。例如,如果您使用 SHIFT 访问第 10 个参数,为了再次访问参数 0(您当前运行的批处理脚本的绝对路径),您可以使用 SHIFT /N 0 将您重置回原来的 0-9论据。 How to pass more than 9 parameters to batch file的可能重复 【参考方案1】:

一个批处理文件中的可访问参数不能超过 10 个(0 到 9 个)(%0 是批处理文件本身)。但是,使用shift 命令将允许您“左移”您的参数,并访问超过第 9 个参数。如果你执行 3 次,你应该得到 %7、%8 和 %9 包含“十”、“十一”和“十二”。

【讨论】:

【参考方案2】:

如果您想使用更多 9 个参数,请使用 shift command。 (如果算上%0参数,其实不止10个参数)

您可以 [...] 使用 shift 命令创建一个批处理文件,该文件可以接受超过 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

如果你有很多参数,你可以用循环替换 shift 命令。下面的 for 循环执行了九次shift,因此%1 将成为第十个参数。

@for /L %%i in (0,1,8) do shift

【讨论】:

但在这种情况下 %7,%8, %9 指的是较旧的值,而不是“十”、“十一”等等...... 请看***.com/questions/21694861/…【参考方案3】:

这是使用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

【讨论】:

【参考方案4】:

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

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

:subr
for %%A in (%*) do (
    echo %%A
)
exit /b

您也可以直接在“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

edit - 如果有人正在处理针对另一个列表的参数并且部分工作是嵌套的,那么使用中介 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

edit 2 - 另外,如果出于某种原因您想在此处添加 shift 方法 - 可能是通过尝试使用shift 然后使用 call :subroutine %* - 请注意它不会工作,因为 %* 实际上按顺序为您提供了所有原始参数,不知道您所做的任何转换。 很遗憾,因为没有原生语法(据我所知)可以将所有参数分组某个参数之后,正如人们可能期望的那样,%3* 会这样做。

【讨论】:

【参考方案5】:

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

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
Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift
Set 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
Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift
Set s=%1 & Set t=%2 & Set u=%3 & Set v=%4 & Set w=%5 & Set x=%6 & Set y=%7 & Set z=%8

我只是把它放在.bat或将使用>9个参数的子程序的顶部,然后你可以使用%a%%z%而不是%1到不存在的%26

太丑了,本来我都是一行一行的

Set a=%1 & Shift & Set b=%1 & Shift &...

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

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

::example; concatenate a bunch of files
Set output=%1
Shift
<insert above behemoth>
type %a% %b% %c% %d% %e% %f% 2>NUL > %output%

这在 bash 中要容易得多

cat $@:2 > "$1"

【讨论】:

以上是关于在 CMD 批处理脚本中调用标签时如何使用超过 9 个参数?的主要内容,如果未能解决你的问题,请参考以下文章

任务计划程序:如何在输出文件的命名中使用 cmd 脚本?

向 exec.Cmd.StdinPipe() 写入超过 4K 字节

调用 VBScript 时在批处理脚本中设置参数

使用 CMD /c 时如何绕过字符限制?

如何在C语言中调用cmd命令?

oracle spool 脚本在 cmd.exe 中工作,但在从代码调用时挂起