如果for循环在Windows批处理中包含通配符*,则计数器不会增加

时间:2014-12-18 01:31:03

标签: batch-file for-loop wildcard

非常感谢在以下问题上提供的任何帮助。我有一个Windows批处理脚本,需要5个命令行参数,我需要在脚本中执行计数,以确保输入了5个参数。该脚本的调用如下所述。通配符可以提到1st,2nd或3rd参数。我使用过第一个。

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的计数。 但是,如果任何命令行参数中有空格

EG。 returnlist.bat“test sh *”“”“”“domainroot”“C:\ tmp \ outfile.txt”

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

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

3 个答案:

答案 0 :(得分:1)

如果你唯一的问题是关于计算论点......你真的需要算一下吗?怎么样?

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

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

答案 1 :(得分:0)

@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

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

答案 2 :(得分:0)

是。当您在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"