windows 此时 %x 出乎意料。批处理脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2190295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
%x was unexpected at this time. batch script
提问by stack
@echo off
for /f "tokens=1,2 delims=," %%x in (my.csv) do (
if %M% LSS %%x set M=%%x
)
echo Max X Value= %M%
Sometimes it works fine, sometimes it fails with following error:
有时它工作正常,有时它会失败并出现以下错误:
%x was unexpected at this time.
回答by paxdiablo
The problem is that you're using %m%
inside a for
loop. This is evaluated when the loop is read (before any iterations at all). In other words, the entire loop, up to and including the closing parenthesis, is read and evaluated before executing. So %m%
will always be it's initial value no matter what you actually set it to within the loop.
问题是,你使用%m%
一个内for
循环。这是在读取循环时(在任何迭代之前)进行评估的。换句话说,在执行之前读取和评估整个循环,直到并包括右括号。因此,%m%
无论您在循环中实际将其设置为什么,都将始终是它的初始值。
An example should hopefully illustrate this:
一个例子应该可以说明这一点:
set val=7
for %%i in (1) do (
set val=99
echo %val%
)
echo %val%
which results in the unexpected (to some):
这导致意外(对某些人):
7
99
simply because the %val%
in the first echo statement is interpreted (i.e., the entire for
loop is interpreted) before any of it is run.
仅仅是因为%val%
第一个 echo 语句中的 被解释(即,整个for
循环被解释)在它的任何一个运行之前。
You need delayed expansion along with something that will force the value of m
to be set to the first %%x
regardless. Using the setlocal
command and !m!
instead of %m%
will delay evaluation of m
until each time the line is executed.
您需要延迟扩展以及强制将 的值m
设置为第一个的东西%%x
。使用setlocal
命令 and!m!
而不是%m%
将延迟评估,m
直到每次执行该行。
In addition, setting m
initially to nothing and forcing it to be %%x
when it isnothing will ensure the first value of %%x
is loaded into m
.
此外,将m
初始设置为空,并%%x
在其为空时强制为空将确保将 的第一个值%%x
加载到m
.
@echo off
setlocal enableextensions enabledelayedexpansion
set m=
for /f "tokens=1,2 delims=," %%x in (my.csv) do (
if "!m!" == "" set m=%%x
if !m! lss %%x set m=%%x
)
echo Max X Value = !m!
endlocal
Using the above code with this my.csv
file:
在此my.csv
文件中使用上述代码:
1,a
2,b
10,c
3,d
results in the output of:
导致输出:
Max X Value = 10
as expected or, for your sample data in another comment:
正如预期的那样,或者,对于您在另一条评论中的示例数据:
422,34
464,55
455,65
421,88
you get:
你得到:
Max X Value = 464
回答by Michael Burr
There's no environment variable named M
set, so when this line is interpreted:
没有名为M
set的环境变量,因此在解释此行时:
if %M% LSS %%x set M=%%x
After the 1st round of replacements, it looks to the interpreter something like
在第一轮替换之后,它看起来像解释器
if LSS %x set M=%x
To avoid the problems that paxdiablo mentionsabout %M%
being expanded only when the loop is first you can use the delayed expansion feature that he discusses, or move testing and setting M
to a subroutine that is called from the loop but exists outside the loop so it gets interpreted (and expanded) on each call:
为了避免问题,paxdiablo提到关于%M%
正在扩大,只有当环是第一,你可以使用延迟扩展功能,他讨论,或移动测试和设置M
的是从循环中调用,但存在外循环子程序所以它被解释(并扩展)每次调用:
@echo off
set M=
for /f "tokens=1,2 delims=," %%x in (my.csv) do (
call :setmax %%x
)
echo Max X Value= %M%
goto :eof
:setmax
if "%M%" == "" set M=%1
if %M% LSS %1 set M=%1
goto :eof
回答by ghostdog74
The problem is in your if %M%
statement. Where is %M% ? declare it first eg
问题出在你的if %M%
陈述中。%M% 在哪里?首先声明它例如
@echo off
set M=""
for /f "tokens=1,2 delims=," %%x in (file) do (
if %M% LSS %%x set M=%%x
)
echo Max X Value= %M%
Alternative, you can use vbscript
替代方案,您可以使用 vbscript
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile = objArgs(0)
Set objFile = objFS.OpenTextFile(strFile)
t=0
Do Until objFile.AtEndOfStream
linenum = objFile.Line
strLine = objFile.ReadLine
s = Split(strLine,",")
For Each num In s
WScript.Echo "num "&num
If Int(num) >= t Then
t=Int(num)
End If
Next
WScript.Echo "Max for line:" & linenum & " is " & t
Loop
example output
示例输出
C:\test>type file
422,34464,55455,65421,88
C:\test>cscript //nologo test.vbs file
Max for line:1 is 65421
UPDATE: To find max value column wise
更新:明智地找到最大值列
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile = objArgs(0)
Set objFile = objFS.OpenTextFile(strFile)
t=0
Do Until objFile.AtEndOfStream
linenum = objFile.Line
strLine = objFile.ReadLine
s = Split(strLine,",")
If Int(s(0)) >= t then
t=Int(s(0))
End If
Loop
WScript.Echo "Max is " & t & " (line: " & linenum & ")"
output
输出
C:\test>type file
422,34
464,55
455,65
421,88
C:\test>cscript //nologo test.vbs file
Max is 464 (line: 2)