web-dev-qa-db-fra.com

% x était inattendu à ce moment-là. script batch

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

Parfois cela fonctionne bien, parfois il échoue avec l'erreur suivante:

%x was unexpected at this time.
11
stack

Le problème est que vous utilisez %m% dans une boucle for. Ceci est évalué lors de la lecture de la boucle (avant toute itération). En d'autres termes, la boucle entière, y compris la parenthèse fermante, est lue et évaluée avant l'exécution. Donc, %m% sera toujours sa valeur initiale, peu importe ce que vous définissez dans la boucle.

J'espère qu'un exemple illustrera ceci:

set val=7
for %%i in (1) do (
    set val=99
    echo %val%
)
echo %val%

ce qui entraîne l'inattendu (pour certains):

7
99

simplement parce que le %val% dans la première instruction echo est interprété (c'est-à-dire que la boucle for entière est interprétée) avant son exécution.

Vous avez besoin d'une expansion retardée avec quelque chose qui va forcer la valeur de m à être définie sur le premier %%x, peu importe. L'utilisation de la commande setlocal et de !m! au lieu de %m% retardera l'évaluation de m jusqu'à chaque exécution de la ligne.

De plus, définir m initialement sur rien et le forcer à être %%x quand - rien ne garantira que la première valeur de %%x est chargée dans 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

En utilisant le code ci-dessus avec ce fichier my.csv:

1,a
2,b
10,c
3,d

aboutit à la sortie de:

Max X Value = 10

comme prévu ou, pour vos exemples de données dans un autre commentaire:

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

vous recevez:

Max X Value = 464
19
paxdiablo

Il n'y a pas de variable d'environnement nommée M set, donc quand cette ligne est interprétée:

if %M% LSS %%x set M=%%x

Après la première série de remplacements, l’interprète a quelque chose comme:

if LSS %x set M=%x

Pour éviter les problèmes que paxdiablo mentionne à propos de %M% n'étant développé que lorsque la boucle est démarrée, vous pouvez utiliser la fonctionnalité d'expansion retardée dont il traite, ou déplacer le test et la définition de M dans un sous-programme appelé à partir de la boucle mais existant en dehors du programme. boucle pour qu'il soit interprété (et développé) à chaque appel:

@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
2
Michael Burr

Le problème est dans votre déclaration if %M%. Où est% M%? déclarez-le d'abord, par exemple

@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, vous pouvez utiliser 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

exemple de sortie

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

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

UPDATE: Pour trouver la valeur maximale par colonne

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

sortie

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

C:\test>cscript //nologo test.vbs file
Max is 464 (line: 2)
0
ghostdog74