tags:

views:

1566

answers:

3
@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, sometime not with following error!! %x was unexpected at this time.

A: 

There's no environment variable named M set, so when this line is interpreted:

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 mentions about %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:

@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
Michael Burr
Though it works sometimes and sometimes don't!!
stack
It will fail with that error message if `M` isn't set to anything before the script is run. If there's already an `M` variable set to something, that error will not occur (though another error might occur if `M` is set to something that makes the command syntactically incorrect again)
Michael Burr
How can i remove % from the end of variable before comparing?
stack
as if variables are 50% 60% 70% i want to get heighest %!!
stack
@stack - I'm not sure what you're asking about in your last 2 comments. When run on my system, the example script I posted works on the example data used in the other answers.
Michael Burr
@Michael I created separate Question: http://stackoverflow.com/questions/2197859/get-maximum-percent-from-csv
stack
@Michael coz your script fails for values:12.00,4225.13,46415.00,45514.00,5213.00,1It gives output as 5 is max coz of string comparison i suppose.
stack
@stack: yeah - it looks like the `LSS` operator works on strings (or maybe integers or strings). Like I said elsewhere, batch files are really bad at complex data processing (for a very small value of complex). I'm sure this problem can be fixed up to be handled, but then there will be some other oddity of batch scripts that makes it fall over when your data changes slightly. I'd suggest using another tool, but if you insist on using batch scripts for this stuff, get Tim Hill's great book on the subject (it can be very cheap from a used vendor): http://www.amazon.com/dp/1578700477
Michael Burr
+1  A: 

The problem is in your if %M% statement. Where is %M% ? declare it first eg

@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

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

output

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

C:\test>cscript //nologo test.vbs file
Max  is 464
ghostdog74
setting M="" doesn't work becase it don't take maximum value! rather it takes the Last value from file.
stack
CSV:--422,34464,55455,65421,88
stack
Hmm, that VBS would be very handy if it actually did the same thing as the cmd file :-) The cmd file just gets you the maximum value of the first 'column' in the csv across all lines, not the maximum on a single line. Shouldn't be too hard to adapt though.
paxdiablo
i see. OP has commented with a single line so I presumed he wants to get the max of each line(row).
ghostdog74
That's better, +1.
paxdiablo
+5  A: 

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.

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.

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.

In addition, setting m initially to nothing and forcing it to be %%x when it is nothing will ensure the first value of %%x is loaded into 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:

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
paxdiablo