【问题标题】:How to pass more than 9 parameters to batch file如何将超过 9 个参数传递给批处理文件
【发布时间】:2014-03-08 19:49:59
【问题描述】:

如何将超过 9 个参数传递给 bach 文件。
我尝试了另一个 SO 问题 How do you utilize more than 9 arguments when calling a label in a CMD batch-script? 但不适合我。

我正在尝试提供保存在批处理中的 url 的运行时值。
我的批次:

start iexplore http://example.com?firstName=%1^&middleName=%2^&lastName=%3^&country=%4^&address=%5^&address2=%6^&address3=%7^&mobileNo=%8^&landlineNo=%9SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT ^&emailAddress=%1^&hobby1=%2^&hobby2=%3^&hobby3=%4^&hobby4=%5^&hobby5=%6

使用时取之前的%1、%2、%3、.....等参数和10th、11th、12th....参数的值 p>

请帮忙!

【问题讨论】:

  • 当您查看这么多参数时,从格式良好的配置文件中读取是否会更好?仅在您还没有想到的情况下询问。
  • @TheOneWhoPrograms...我必须将它从 java 传递给批处理,别无他法...谢谢
  • ...可以从java存储到文件中,然后从批处理中读取,但我想那是低效的......祝你好运!提出一个好问题会给 +1。

标签: batch-file


【解决方案1】:

将前九个参数保存在一个变量中。然后多次调用 shift ,然后才使用其余的:

set "v=http://example.com?firstName=%1&middleName=%2&lastName=%3&country=%4&address=%5&address2=%6&address3=%7&mobileNo=%8&landlineNo=%9"
shift
shift
shift
shift
shift
shift
shift
shift
shift
start iexplore %v%&emailAddress=%1&hobby1=%2&hobby2=%3&hobby3=%4&hobby4=%5&hobby5=%6

【讨论】:

  • @Stephan shift /n 表示它应该从第 n 个参数开始,即不要在 n 之前移动参数。 shift /9 无效,无论如何都不会产生任何影响。 technet.microsoft.com/en-us/library/bb491002.aspx
  • 我怎样才能传递空白......即,%6="" 或 " "的值......如果我使用 "" 或 " " 传递,它不会检测值,取下一个作为%6的值
【解决方案2】:

您可以通过一次添加一个参数来减少出错的可能性。这样,如果您必须在中间添加一个新参数或取出一个参数,则无需重新编号其余参数:只需更改两行即可。希望您的参数中没有空格,但这是另一回事。

set v=http://example.com
rem first parameter is ?: subsequent ones are &
set sep=?
call :add firstName %1
shift
call :add middleName %1
shift
call :add lastName %1
shift
...
start iexplore "%v%"
goto :eof
:add
    rem add a parameter
    set v=%v%%sep%%1=%2
    set sep=&
    goto :eof

【讨论】:

    【解决方案3】:
    :: set PARAMn and count parameters
    SET /a paramcount=1
    :paramloop
    SET "param%paramcount%=%~1"
    IF DEFINED param%paramcount% SET /a paramcount+=1&shift&GOTO paramloop
    SET /a paramcount -=1
    

    此例程应该为您设置param1..paramn,并带有计数。

    很遗憾,您发布的代码似乎难以辨认,因此实际使用这些值 - 这取决于您。

    【讨论】:

      【解决方案4】:

      盆地的解决方案应该有效。要解决问题中代码的问题:您不能只将多个命令放在一行中,也不能在另一个命令的参数中间使用 shift 命令。基本上,您必须将所有内容分开,如另一个答案所示。为了使其更简洁易读,我会这样做:

      set "ieargs=http://example.com?firstName=%1^&middleName=%2^&lastName=%3^&country=%4^&address=%5^&address2=%6^&address3=%7^&mobileNo=%8^&landlineNo=%9"
      
      @for /L %%i in (0,1,8) do shift
      set "ieargs=%ieargs%^&emailAddress=%1^&hobby1=%2^&hobby2=%3^&hobby3=%4^&hobby4=%5^&hobby5=%6"
      
      start iexplore %ieargs%
      

      前九个参数保存在字符串中。然后它循环和移位九次,所以%1 将成为第一个参数。

      如果您需要更多参数,您可以根据需要多次重复:

      set "ieargs=http://example.com?firstName=%1^&middleName=%2^&lastName=%3^&country=%4^&address=%5^&address2=%6^&address3=%7^&mobileNo=%8^&landlineNo=%9"
      
      @for /L %%i in (0,1,8) do shift
      set "ieargs=%ieargs%^&emailAddress=%1^&hobby1=%2^&hobby2=%3^&hobby3=%4^&hobby4=%5^&hobby5=%6^&hobby6=%7^&hobby7=%8^&hobby8=%9"
      
      @for /L %%i in (0,1,8) do shift
      set "ieargs=%ieargs%^&hobby9=%1^&hobby10=%2^&hobby11=%3^&hobby12=%4"
      
      start iexplore %ieargs%
      

      【讨论】:

        【解决方案5】:

        这是一个更简单的解决方案,假设您只想将值传递给另一个程序。此示例允许将多达 27 个参数传递给 zip...

        @echo OFF
        set ZipArgs=%1 %2 %3 %4 %5 %6 %7 %8 %9
        for /L %%i in (0,1,8) do @shift
        set ZipArgs=%ZipArgs% %1 %2 %3 %4 %5 %6 %7 %8 %9
        for /L %%i in (0,1,8) do @shift
        set ZipArgs=%ZipArgs% %1 %2 %3 %4 %5 %6 %7 %8 %9
        "C:\Program Files\WinZip\wzzip.exe" %ZipArgs%
        

        第一行只是关闭将每一行回显到屏幕上。以 set ZipArgs 开头的行使用命令行中的接下来的 9 个参数构建环境变量 ZipArgs。 “for”行使用 SHIFT 命令丢弃前 9 个参数,将接下来的 9 个参数置于“前面”。最后一行执行 zip,将组装的参数值传递给它。

        您可以通过添加代码来检查命令行上的参数数量并采取适当的行动来使事情复杂化,但这对我来说很好。

        【讨论】:

          【解决方案6】:

          这是一个简单的答案: shift 是键,然后循环值并将它们分配给变量。 设置计数器以指示每个参数是哪个变量。

          示例将字母放入批处理文件并将它们设置为 arg1、arg2 等变量。

          批处理文件 test.bat 示例:

          @echo off
          
          set /a counter=1
          :ARGLBEG
          if "%1"=="" goto ARGLEND
          set arg%counter%=%1
          goto ARGNEXT 
          
          :ARGNEXT
          shift
          set /a counter=%counter%+1
          goto ARGLBEG
          
          :ARGLEND
          echo "List values."
          set arg
          
          echo "Just one value, arg9."
          echo %arg9%
          goto end
          
          :end
          

          如何使用 test.bat 以及结果如何:

          test.bat A B c d e F G H i J k L M N O P Q R S t u v x y z
          

          结果。

          "List values."
          arg1=A
          arg10=J
          arg11=k
          arg12=L
          arg13=M
          arg14=N
          arg15=O
          arg16=P
          arg17=Q
          arg18=R
          arg19=S
          arg2=B
          arg20=t
          arg21=u
          arg22=v
          arg23=x
          arg24=y
          arg25=z
          arg3=c
          arg4=d
          arg5=e
          arg6=F
          arg7=G
          arg8=H
          arg9=i
          "Just one value, arg9."
          i
          

          【讨论】:

            【解决方案7】:
            @echo off
            set /a a=0
            :9
            set CustomVar%a%=%1
            @shift
            set /a a=%a%+1
            if %a%==300 goto :8
            goto :9
            :8
            @echo on
            

            【讨论】:

            • 请避免对同一个问题发布两个答案,而无需任何解释来区分两者。我已删除您的旧答案。
            【解决方案8】:

            我的替代方案允许您跳过任意数量的参数并且不需要移动

            SETLOCAL
              SET /a SKIP=3
              CALL :SkipAndExec SKIP THESE VARS echo numbers: 1 2 3 4 5 6 7 8 9 0 11 12 13 14
            ENDLOCAL
            GOTO:eof
            
            :SkipAndExec
            SETLOCAL
            SET /a n=0
            FOR %arg IN (%*) DO (
              SET /a n=n+1
              IF %n% GT %SKIP% (
                :: here you could compose a string to use later
                SET _CMD_=%_CMD_% %arg%
              )
            )
            :: here you could call another function and pass in %_CMD_%
            CALL %_CMD_%
            GOTO:eof
            

            如果您执行该脚本,它将打印:

            numbers: 1 2 3 4 5 6 7 8 9 0 11 12 13 14
            

            【讨论】:

              【解决方案9】:

              使用%*Command Line arguments (Parameters)

              寻找如何将任意数量的参数传递给可执行文件的人:

              @ECHO OFF
              SET "EXECUTABLE=C:\PATH\TO\MY\EXECUTABLE.EXE"
              CALL %EXECUTABLE% %*
              

              回答问题(openurl.bat):

              @ECHO OFF
              SETLOCAL EnableDelayedExpansion
              
              SET URL=
              SET /A BASECONCATENATED=0
              FOR %%A IN (%*) DO (
                  SET PARAM=%%A
                  SET PARAM=!PARAM:"=!
              
                  IF !BASECONCATENATED! EQU 0 (
                      SET "URL=!URL!!PARAM!^?"
                      SET /A BASECONCATENATED=1
                  ) ELSE (
                      SET "URL=!URL!!PARAM!^&"
                  ) 
              )
              
              SET URL=!URL:~0,-1!
              
              CALL "%SYSTEMDRIVE%\Program Files\Internet Explorer\iexplore.exe" "!URL!"
              
              REM EXAMPLE cmd.exe "openurl.bat" http://www.example.com/addPerson.php "firstName=Juan" "lastName=Cerezo" "hobby1=Coding" "hobby2=Learning" "hobby3=Play Videogames"
              

              【讨论】:

              • 没有 255 个参数的限制。它仅受 8191 个字符的行长限制,我测试并因此得到 4094 个 args 的限制,A A A A A ...
              • 是的,这是真的!!谢谢!! :D
              • 使用%* 传递参数并非在所有情况下都有效。想一个简单的myBatch.bat C:\Docs^&Music
              【解决方案10】:

              您可以使用shift 命令,其中shifts 参数返回1 步,例如%9 将存储在%8%8 将存储在%7 等中,所以如果那样如果有意义的话,第 9th 参数中会有 10th 参数的空间,这是一个示例:

              @echo off
              set arg1=%~1
              set arg2=%~2
              set arg3=%~3
              set arg4=%~4
              set arg5=%~5
              set arg6=%~6
              set arg7=%~7
              set arg8=%~8
              set arg9=%~9
              shift
              set arg10=%~9
              shift
              set arg11=%~9
              shift
              set arg12=%~9
              

              而不是使用 %~1 使用 %arg1% 等,并使用 10th、11th、12th 参数你将使用%arg10%%arg11%%arg12%

              【讨论】:

                【解决方案11】:

                处理参数中的 * 示例:

                @ECHO OFF
                SETLOCAL DISABLEDELAYEDEXPANSION
                
                CALL testLIMIT.bat 3 4 2 1 2 3 4 5 3 2 1 2 3 4 5 6 5 4 3 2 1 2 3 4 5 6 7 6 5 4 3 2 1 A Star * is Born twice * now
                
                ECHO HOME
                Pause
                exit
                
                @ECHO OFF
                SETLOCAL EnableDelayedExpansion
                
                REM :: Used to define the Array Index values and Range
                set _I=0
                
                REM :: The Core piece in recieving Large numbers of Parameters.
                REM :: Processes all Parameters. Tested to over 2500 Parameters.
                
                Set StarTest=0
                FOR %%a in (%*) DO (
                    IF EXIST "%%~a" Call :StarTest
                    IF NOT EXIST "%%~a" (
                    CALL Set /a _I+=1
                    CALL Set "arg[!_I!]=%%a"
                    CALL Set StarTest=0
                    )
                )
                
                
                REM :: Loops through the Array to display Parameter Values.
                
                FOR /L %%a in (1,1,!_I!) DO (
                ECHO !arg[%%a]!
                )
                
                echo %_I% Arguments received.
                Pause
                GOTO :EOF
                
                :StarTest
                IF %StarTest% GTR 0 GOTO :EOF
                Set /a StarTest+=1
                Set /a _I+=1
                Set "arg[!_I!]=*"
                GOTO :EOF
                

                使用 Shift 处理参数完全不需要,更不用说乱七八糟了。

                与 Marcels Answer 类似,以下方法将处理异常大量的参数,而无需知道将收到多少个参数。

                它使用带有 * 通配符的基本 For 循环来处理所有标记并将它们分配给一个数组,还为文件接收到多少个参数以启用处理提供一个值。

                
                @ECHO OFF
                SETLOCAL EnableDelayedExpansion
                
                REM :: Used to define the Array Index values and Range
                set _I=0
                
                REM :: The Core piece in recieving Large numbers of Parameters.
                REM :: Processes all Parameters. Tested to over 2500 Parameters.
                
                FOR %%a in (%*) DO (
                Set /a _I+=1
                Set "arg[!_I!]=%%a"
                )
                
                REM :: Loops through the Array to display Parameter Values. Modify as needed to Process Parameters.
                
                FOR /L %%a in (1,1,!_I!) DO (
                ECHO !arg[%%a]!
                )
                
                echo %_I% Arguments received.
                Pause
                GOTO :EOF
                
                

                【讨论】:

                • 如果您使用A star * is born 调用您的批次,这将不起作用。顺便提一句。这与Marcel Valdez Orozco的解决方案相同
                • 关于 Marcels 的回答,我特意提到了他的回答和我的相似之处——但也许我没有在我的回答中强调 Array 元素的价值/应用。关于用“A Star * is Born”打电话的影响,这是一个非常有趣的学习。我在调用中使用 * 进行了测试,结果让我有些惊讶——当前目录中的所有文件名(包括扩展名)都被拾取并包含在数组中。对于某些应用程序,这种行为可能会被操纵以发挥优势。
                • 假设传递的其他参数不是文件路径,在调用中包含 * 产生的标记可以使用 IF Not Exist "%%~a" () 在设置之前检查数组的参数。现在我很好奇如何(如果可能的话)在调用或处理期间逃脱星形以防止此输出并保留原始字符串/参数。嗨嗨嗨嗨,我在试验和研究。 "\" 或 "^" 将转义符号,但不包含它。
                • *? 没有被 CALL扩展,它们被简单的 FOR 扩展,不能被转义。您可以使用FOR /F,但不能用引号/空格分隔参数。然后你必须编写一个功能齐全的参数解析器
                • 我知道它在循环过程中被扩展了,但是我想确定在它作为参数发送时是否有一种方法可以修改包含 * 的字符串字符串可以随后处理。对最简单方法的初步想法是将符号替换为另一个字符串,并在循环期间检测这种替换以重建原始字符串。
                猜你喜欢
                • 2010-09-06
                • 1970-01-01
                • 1970-01-01
                • 2018-03-28
                • 1970-01-01
                • 2018-06-15
                • 1970-01-01
                相关资源
                最近更新 更多