【问题标题】:Is there a way to pass more than 9 variables to another batch file as arguments? [duplicate]有没有办法将超过 9 个变量作为参数传递给另一个批处理文件? [复制]
【发布时间】:2018-06-15 21:18:01
【问题描述】:

我正在尝试将 14 个变量从一个文件批量传递到另一个文件,但它在第 9 个变量之后停止工作。

这是我使用的代码和输出。

caller.bat

代码

@echo off
set vara=A
set varb=B
set varc=C
set vard=D
set vare=E
set varf=F
set varg=G
set varh=H
set vari=I
set varj=J
set vark=K
set varl=L
set varm=M
set varn=N

echo Variables set in caller.bat:
echo %vara%
echo %varb%
echo %varc%
echo %vard%
echo %vare%
echo %varf%
echo %varg%
echo %varh%
echo %vari%
echo %varj%
echo %vark%
echo %varl%
echo %varm%
echo %varn%

echo Calling passTo.bat
call passTo.bat %vara% %varb% %varc% %vard% %vare% %varf% %varg% %varh% %vari% %varj% %vark%  %varl% %varm% %varn%
pause>nul
caller.bat

输出

Variables set in caller.bat:
A
B
C
D
E
F
G
H
I
J
K
L
M
N
Calling passTo.bat
passTo.bat

代码

echo Inside passTo.bat
set vara=%1
set varb=%2
set varc=%3
set vard=%4
set vare=%5
set varf=%6
set varg=%7
set varh=%8
set vari=%9
set varj=%10
set vark=%11
set varl=%12
set varm=%13
set varn=%14
echo vara: %vara%
echo varb: %varb%
echo varc: %varc%
echo vard: %vard%
echo vare: %vare%
echo varf: %varf%
echo varg: %varg%
echo varh: %varh%
echo vari: %vari%
echo varj: %varj%
echo vark: %vark%
echo varl: %varl%
echo varm: %varm%
echo varn: %varn%

输出来自passTo.bat

Inside passTo.bat
vara: A
varb: B
varc: C
vard: D
vare: E
varf: F
varg: G
varh: H
vari: I
varj: A0
vark: A1
varl: A2
varm: A3
varn: A4

可以看出它在第 9 个之后就搞砸了,它只是开始在变量的末尾添加数字。我正在为自己做这件事,看看我是否可以将它实现到随机化器以选择名称。

【问题讨论】:

  • shift /? 了解如何。这不是直截了当的。如果需要随机数,请参阅帮助末尾的set /?
  • 我会把 shift / 放在哪里?
  • 阅读帮助并找出答案。你必须重写你的代码。
  • 您也可以使用 for 循环来迭代 %*
  • 你只需要复制文本输出并放在这里,不需要截图

标签: batch-file batch-processing


【解决方案1】:

来自shift /?

C:\Users\iBug>shift /?
Changes the position of replaceable parameters in a batch file.

SHIFT [/n]

If Command Extensions are enabled the SHIFT command supports
the /n switch which tells the command to start shifting at the
nth argument, where n may be between zero and eight.  For example:

    SHIFT /2

would shift %3 to %2, %4 to %3, etc. and leave %0 and %1 unaffected.

因此,如果您有 12 个参数,则可以使用 3 个shift。之后,原来的第 1 和第 2 个参数将不再可用(以及%0),而原来的第 10 到第 12 个参数将作为%7%8%9 可用。

示例代码:

REM Filename: foo.bat
@ECHO OFF
ECHO %1 %2 %3 %4
SHIFT
SHIFT
SHIFT
ECHO %1 %2 %3 %4
ECHO %6 %7 %8 %9

像这样运行它:

C:\Users\iBug>foo.bat a b c d e f g h i j k l
a b c d
d e f g
i j k l

C:\Users\iBug>

您也可以使用开关保留前 8 个参数,并且每次只丢弃第 9 个参数:

SHIFT /8

【讨论】:

    【解决方案2】:

    可以通过打开命令提示符窗口并运行help commandcommand /? 来获取和阅读cmd.exe 的内部命令的帮助。用help callcall /?help forfor /?help shiftshift /? 试试这个。

    ping.exe 文件夹中的ping.exexcopy.exe 等标准控制台应用程序支持也使用选项/? 执行以显示帮助。试试ping /?choice /?find /?。这些可执行文件也称为 Windows 默认可用的外部命令(取决于 Windows 版本),但不是 cmd.exe 的内部命令。

    这是caller.bat 的代码,其中包含一些非常难看的字符串:

    @echo off
    setlocal
    set "vara="""
    set "varb=B"
    set "varc="C""
    set "vard=Hello!"
    set "vare="%%PATH%%""
    set "varf=F"
    set "varg=G"
    set "varh=Operators: &()[]{}^=;!'+,`~<>|"
    set "vari=I"
    set "varj=J"
    set "vark=K"
    set "varl=!PATHEXT!"
    set "varm=M"
    set "varn=N"
    
    cls
    echo Variables set in %~nx0:
    echo/
    set var
    echo/
    echo Calling passTo.bat
    echo/
    setlocal EnableDelayedExpansion
    call passTo.bat %vara%  %varb% %varc% !vard! !vare! %varf% %varg% "!varh!" %vari% %varj% %vark% "!varl!" %varm% %varn%
    endlocal
    endlocal
    

    这个批处理文件的输出是:

    Variables set in caller.bat:
    
    vara=""
    varb=B
    varc="C"
    vard=Hello!
    vare="%PATH%"
    varf=F
    varg=G
    varh=Operators: &()[]{}^=;!'+,`~<>|
    vari=I
    varj=J
    vark=K
    varl=!PATHEXT!
    varm=M
    varn=N
    
    Calling passTo.bat
    

    这里是passTo.bat 的代码,其中包含三种处理传递参数的方法。

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem Is this batch file called with at least 1 argument string?
    if not "%~1" == "" goto MainCode
    rem It can be even an empty argument string, i.e. just "".
    if #%1 == #"" goto Maincode
    echo %~nx0 is called with no argument.
    goto EndBatch
    
    
    rem ArgumentToVariable is a subroutine called from FOR loop below.
    :ArgumentToVariable
    call set "Letter=%%Indices:~%Index%,1%%
    set var%Letter%=%1
    set /A Index+=1
    goto :EOF
    
    
    :MainCode
    echo Inside %~nx0 executed with the arguments:
    echo %*
    set "Index=0"
    set "Indices=abcdefghijklmn"
    
    for %%I in (%*) do call :ArgumentToVariable %%I
    
    echo/
    echo Arguments list processed with command FOR with using a subroutine:
    echo/
    set var
    rem End current local environment to discard all environment variables.
    endlocal
    
    
    rem Setup a new local environment to recreate all variables once again.
    setlocal EnableExtensions EnableDelayedExpansion
    set "Index=0"
    set "Indices=abcdefghijklmn"
    
    for %%I in (%*) do (
        set "Letter=Indices:~!Index!,1"
        call set "Letter=%%!Letter!%%"
        set var!Letter!=%%I
        set /A Index+=1
    )
    
    echo/
    echo Arguments list processed with command FOR with using delayed expansion:
    echo/
    set var
    rem End current local environment to discard all environment variables.
    endlocal
    
    rem Setup a new local environment to recreate all variables once again.
    setlocal EnableExtensions DisableDelayedExpansion
    set "Index=0"
    set "Indices=abcdefghijklmn"
    
    :ShiftLoop
    call set "Letter=%%Indices:~%Index%,1%%
    set var%Letter%=%1
    set /A Index+=1
    shift
    if not "%~1" == "" goto ShiftLoop
    if #%1 == #"" goto ShiftLoop
    
    echo/
    echo Arguments list processed with command SHIFT:
    echo/
    set var
    
    :EndBatch
    endlocal
    
    echo/
    echo Variables list as defined by parent batch file:
    echo/
    set var
    

    passTo.bat 的输出是:

    Inside passTo.bat executed with the arguments:
    ""  B "C" Hello! "C:\Windows\System32;C:\Windows;C:\Windows\system32\wbem" F G "
    Operators: &()[]{}^^=;!'+,`~<>|" I J K "!PATHEXT!" M N
    
    Arguments list processed with command FOR with using a subroutine:
    
    vara=""
    varb=B
    varc="C"
    vard=Hello!
    vare="C:\Windows\System32;C:\Windows;C:\Windows\system32\wbem"
    varf=F
    varg=G
    varh="Operators: &()[]{}^^^^=;!'+,`~<>|"
    vari=I
    varj=J
    vark=K
    varl="!PATHEXT!"
    varm=M
    varn=N
    
    Arguments list processed with command FOR with using delayed expansion:
    
    vara=""
    varb=B
    varc="C"
    vard=Hello\Windows\System32
    vare=C:\Windows
    varf=C:\Windows\system32\wbem" F G "Operators:
    varg=&()[]{}
    varh=PATHEXT" M N
    vari=I
    varj=J
    vark=K
    varl=!PATHEXT!
    varm=M
    varn=N
    
    Arguments list processed with command SHIFT:
    
    vara=""
    varb=B
    varc="C"
    vard=Hello!
    vare="C:\Windows\System32;C:\Windows;C:\Windows\system32\wbem"
    varf=F
    varg=G
    varh="Operators: &()[]{}^^=;!'+,`~<>|"
    vari=I
    varj=J
    vark=K
    varl="!PATHEXT!"
    varm=M
    varn=N
    
    Variables list as defined by parent batch file:
    
    vara=""
    varb=B
    varc="C"
    vard=Hello!
    vare="%PATH%"
    varf=F
    varg=G
    varh=Operators: &()[]{}^=;!'+,`~<>|
    vari=I
    varj=J
    vark=K
    varl=!PATHEXT!
    varm=M
    varn=N
    

    通过比较列表可以看出,一些参数字符串不是通过参数列表从批处理文件caller.bat 未经修改地传递到passTo.bat

    最好的结果是通过使用命令SHIFT 将字符串通过参数传递给另一个批处理文件的方法产生的。但真正最好的解决方案是使用环境变量将字符串从一个批处理文件传递到另一个批处理文件,如最后一个变量列表所示与caller.bat 的输出相同,因为passTo.bat 输出由父批处理文件定义的环境变量。

    这三种方法都可以很好地解析简单的字符串,例如用双引号括起来的文件名字符串,并且通过参数列表不包含 %!^

    并且使用像var_1var_2、...或var[1]var[2]等变量命名方案将使参数和变量处理绝对更容易,因为整数可以在获取时轻松递增列表中的下一个字母更难实现。

    另见Copy text from a Windows CMD window to clipboard

    【讨论】:

      猜你喜欢
      • 2014-03-08
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多