【问题标题】:Counter doesn't get incremented if the for loop contains a wild card character * in windows batch如果 for 循环在 Windows 批处理中包含通配符 *,则计数器不会增加
【发布时间】:2014-12-18 01:31:03
【问题描述】:

非常感谢就以下问题提供的任何帮助。我有一个带有 5 个命令行参数的 Windows 批处理脚本,我需要在脚本中执行计数以确保输入了 5 个参数。该脚本的调用如下所述。第一个、第二个或第三个参数都可以用通配符提及。我用的是第一个。

returnlist.bat "sh*" "" "" "domainroot" "C:\tmp\outfile.txt"

我使用以下代码块来评估计数器

set /A argC=0
for %%x in (%*) do Set /A argC+=1
echo %argC%

在这种情况下,返回的计数是 4 而不是 5,并且脚本失败,因为预期有 5 个参数。但是,如果我们不在命令行参数中使用 *,那么我们会返回正确的计数 5。

因此我将代码更改为

Set /A argC=0
Set argStr=%*

:SplitParams
if "!argStr!" NEQ "" (
        for /F "tokens=1* delims= " %%i in ("!argStr!") do (
                Set myArr[!argC!]=%%i
                Set /A argC+=1
                Set argStr=%%j
                goto :SplitParams
        )
)

这会处理通配符并在包含 * 时返回计数 5。 但是,如果任何命令行参数中有空格

例如。 returnlist.bat "test sh*" "" "" "domainroot" "C:\tmp\outfile.txt"

然后第一个参数被视为 2 个参数,因此返回的计数是 6 而不是 5,这再次导致脚本失败,因为预期只有 5 个参数。

非常感谢在此问题上提供的任何帮助。我需要能够指定通配符,并且参数中也可以存在空格。

【问题讨论】:

    标签: batch-file for-loop wildcard


    【解决方案1】:

    如果您唯一的问题是关于论点的计数……您真的需要计数吗?这个怎么样?

    if "%~5"=="" echo.*** ERROR *** Not enough arguments & pause & goto :eof
    

    我还注意到您正在尝试使用延迟扩展,但尚未启用它。有额外的代码吗?

    【讨论】:

    • 是的,我就是这样做的。但是,它最多只能用于 9 个预期参数。除此之外,必须保存这些值并使用 SHIFT。
    【解决方案2】:
    @ECHO OFF
    SETLOCAL
    FOR /f "delims=" %%a IN (q27537815.txt) DO (
     CALL :returnlist %%a
    )
    
    GOTO :EOF
    
    :returnlist
    :: remove variables starting arg
    FOR  /F "delims==" %%a In ('set arg 2^>Nul') DO SET "%%a="
    SET /a argcount=0
    SET "empty="
    SET "wildcards="
    :argloop
    SET "arg=%1"
    IF NOT DEFINED arg GOTO report
    
    SET /a argcount+=1
    SET "arg=%~1"
    IF NOT DEFINED arg SET empty=%empty% %argcount%&shift&GOTO argloop
    SET "arg%argcount%=%~1"
    ECHO %arg%|FIND "*" >NUL
    IF NOT ERRORLEVEL 1 SET "wildcards=%wildcards% %argcount%
    SHIFT
    GOTO argloop
    
    :report 
    ECHO %argcount% arguments IN %*
    IF DEFINED empty ECHO arguments%empty% are empty
    IF DEFINED wildcards ECHO arguments%wildcards% contain wildcards
    SET arg
    GOTO :eof
    

    此演示使用此数据文件q27537815.txt

    "only one parameter"
    "two" "but who's counting"
    "now three" "*" "#2 is asterisk"
    "4" "" "*" "four-empty-star-thisstring"
    "5" "*" "" "*" "five - two asterisks, middle empty"
    "6" "too" "many" "parameters" "this" "time"
    "5" "*" "*" "*" "five - three asterisks"
    5 * ""  * five-two-asterisks-middle-empty
    6 too many parameters this time
    

    生成此报告

    1 arguments IN "only one parameter"
    arg1=only one parameter
    argcount=1
    2 arguments IN "two" "but who's counting"
    arg1=two
    arg2=but who's counting
    argcount=2
    3 arguments IN "now three" "*" "#2 is asterisk"
    arguments 2 contain wildcards
    arg1=now three
    arg2=*
    arg3=#2 is asterisk
    argcount=3
    4 arguments IN "4" "" "*" "four-empty-star-thisstring"
    arguments 2 are empty
    arguments 3 contain wildcards
    arg1=4
    arg3=*
    arg4=four-empty-star-thisstring
    argcount=4
    5 arguments IN "5" "*" "" "*" "five - two asterisks, middle empty"
    arguments 3 are empty
    arguments 2 4 contain wildcards
    arg1=5
    arg2=*
    arg4=*
    arg5=five - two asterisks, middle empty
    argcount=5
    6 arguments IN "6" "too" "many" "parameters" "this" "time"
    arg1=6
    arg2=too
    arg3=many
    arg4=parameters
    arg5=this
    arg6=time
    argcount=6
    5 arguments IN "5" "*" "*" "*" "five - three asterisks"
    arguments 2 3 4 contain wildcards
    arg1=5
    arg2=*
    arg3=*
    arg4=*
    arg5=five - three asterisks
    argcount=5
    5 arguments IN 5 * ""  * five-two-asterisks-middle-empty
    arguments 3 are empty
    arguments 2 4 contain wildcards
    arg1=5
    arg2=*
    arg4=*
    arg5=five-two-asterisks-middle-empty
    argcount=5
    6 arguments IN 6 too many parameters this time
    arg1=6
    arg2=too
    arg3=many
    arg4=parameters
    arg5=this
    arg6=time
    argcount=6
    

    哪个应该适当地提供您的计数。

    【讨论】:

      【解决方案3】:

      是的。当您在 for 命令中放置带有通配符的参数时,通配符总是被扩展的。您应该通过shift 命令以旧方式获取参数:

      @echo off
      setlocal EnableDelayedExpansion
      
      set argC=0
      :SplitParams
         set /A argC+=1
         set myArr[%argC%]=%1
         shift
      if defined myArr[%argC%] goto SplitParams
      
      set /A argC-=1
      echo Number of params: %argC%
      for /L %%i in (1,1,%argC%) do echo %%i - !myArr[%%i]!
      

      例如:

      C:\> returnlist.bat "test sh*" "" "" "domainroot" "C:\tmp\outfile.txt"
      Number of params: 5
      1 - "test sh*"
      2 - ""
      3 - ""
      4 - "domainroot"
      5 - "C:\tmp\outfile.txt"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-26
        • 1970-01-01
        • 1970-01-01
        • 2015-08-05
        • 1970-01-01
        • 1970-01-01
        • 2018-02-27
        • 1970-01-01
        相关资源
        最近更新 更多