Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows %x在这个时候是出乎意料的。批处理脚本_Windows_Batch File_Cmd - Fatal编程技术网

Windows %x在这个时候是出乎意料的。批处理脚本

Windows %x在这个时候是出乎意料的。批处理脚本,windows,batch-file,cmd,Windows,Batch File,Cmd,有时工作正常,有时出现以下错误: @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% 没有名为Mset的环境变量,因此解释此行时: %x was unexpected at this time. 在第一轮替换之后,在口译员看来 if %M% LSS %%x set M=%%x 为避免仅在循环首次出现时才扩展%M%的问题,您可以

有时工作正常,有时出现以下错误:

@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%

没有名为
M
set的环境变量,因此解释此行时:

%x was unexpected at this time.
在第一轮替换之后,在口译员看来

if %M% LSS %%x set M=%%x
为避免仅在循环首次出现时才扩展
%M%
的问题,您可以使用他讨论的延迟扩展功能,或将测试和设置
M
移动到从循环调用但存在于循环外部的子例程,以便在每次调用时对其进行解释(和扩展):

if LSS %x set M=%x

问题出在您的
if%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
或者,您可以使用vbscript

@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%
示例输出

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
更新:按列查找最大值

C:\test>type file
422,34464,55455,65421,88

C:\test>cscript //nologo test.vbs file
Max for line:1 is 65421
输出

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 & ")"

问题是您在
for
循环中使用了
%m%
。在读取循环时(在任何迭代之前)对其进行评估。换句话说,在执行之前,将读取并计算整个循环(包括右括号)。因此,
%m%
将始终是它的初始值,无论您在循环中实际将其设置为什么

希望通过一个例子来说明这一点:

C:\test>type file
422,34
464,55
455,65
421,88

C:\test>cscript //nologo test.vbs file
Max is 464 (line: 2)
这会导致(某些人)意外的结果:

原因很简单,第一个echo语句中的
%val%
在运行任何循环之前被解释(即,整个
for
循环被解释)

您需要延迟扩展,同时需要强制将
m
的值设置为第一个
%%x
。使用
setlocal
命令和
!m
而不是
%m%
将延迟
m
的计算,直到每次执行该行

此外,最初将
m
设置为“无”,并在其为“无”时强制将其设置为
%%x
,将确保
%%x
的第一个值加载到
m

7
99
将上述代码与此
my.csv
文件一起使用:

@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
结果如下:

1,a
2,b
10,c
3,d
如预期,或者,对于另一条评论中的示例数据:

Max X Value = 10
你会得到:

422,34
464,55
455,65
421,88

设置M=”“不起作用,因为它不取最大值!相反,它从file.CSV中获取最后一个值:--422,34 464,55 455,65 421,88Hmm,如果VBS实际执行与cmd文件相同的操作,它将非常方便:-)cmd文件只会在所有行中获取CSV中第一个“列”的最大值,而不是单行中的最大值。不过适应起来应该不会太难,我明白了。OP只注释了一行,所以我推测他希望获得每行(行)的最大值。如果在脚本运行之前未将
M
设置为任何值,它将失败并显示错误消息。如果已经有一个
M
变量设置为某个值,则不会发生该错误(尽管如果
M
设置为使命令语法再次不正确的值,则可能会发生另一个错误)。在比较之前,我如何从变量末尾删除%@堆栈-我不确定你在最后2条评论中问了什么。在我的系统上运行时,我发布的示例脚本对其他答案中使用的示例数据起作用。@Michael我创建了单独的问题:
422,34
464,55
455,65
421,88
Max X Value = 464