2010-05-26 7 views
38

J'essaie de lire les lignes de texte d'un fichier et d'incrémenter un compteur afin de simuler un tableau sous DOS. Je voudrais être en mesure de stocker les lignes de texte dans un tableau DOS pour un traitement ultérieur.Comment incrémenter une variable DOS dans une boucle FOR/F?

Ma tentative actuelle est:

set TEXT_T="myfile.txt" 

set /a c=1 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
set /a c=c+1 
echo %%i, %c% 
) 

Mais la variable c est pas incrémenter; il reste à 1.

Suggestions bienvenues.

Merci, Mike

Répondre

72

Le problème avec l'extrait de code est les variables sont ainsi élargies. L'expansion variable est généralement effectuée lors de la première lecture d'une instruction. Dans votre cas, la totalité de la boucle FOR et son bloc sont lus et toutes les variables, à l'exception des variables de boucle, sont étendues à leur valeur actuelle.

Cela signifie %c% dans votre echo %%i, %c% étendu instantanément et est donc réellement utilisé comme echo %%i, 1 dans chaque itération de boucle.

Vous avez donc besoin d'une extension de variable retardée. Trouver une bonne explication à ce sujet here.

Les variables devant être étendues en différé sont référencées par !VARIABLE! au lieu de %VARIABLE%. Mais vous devez activer cette fonction avec setlocal ENABLEDELAYEDEXPANSION et le réinitialiser avec un endlocal correspondant.

Votre code modifié ressemblerait à quelque chose comme ça:

set TEXT_T="myfile.txt" 

set /a c=1 

setlocal ENABLEDELAYEDEXPANSION 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
    set /a c=c+1 

    echo %%i, !c! 
) 

endlocal 
+0

Super Duper! C'est exactement ce dont j'avais besoin. J'ai modifié le script en conséquence et il fonctionne maintenant comme prévu. Merci pour la réponse rapide. - Mike – Mike

+3

@Mike: vous devriez marquer cette réponse comme acceptée si elle a résolu votre problème! – Sk8erPeter

+0

@Frank Bollack. merci beaucoup pour cette explication, j'ai appris quelque chose de nouveau. J'ai utilisé cette technique pour répondre à cette autre question: http://serverfault.com/questions/664202/batch-file-that-kills-a-certain-process. Cela fonctionne, mais je ne suis pas sûr de la façon dont je devrais référencer les variables _outside_ la boucle FOR. Cela fait-il une différence, en utilisant! C! ou% c%, en ce que SI j'ai après le FOR? – pgr

3

Je voudrais ajouter qu'en cas de créer la notation des variables locales dans la boucle, ils doivent être développés en utilisant le bang comme (!) bien. L'extension de l'exemple ci-dessus à https://stackoverflow.com/a/2919699, si nous voulons créer des noms de fichiers de sortie à base de contre-

set TEXT_T="myfile.txt" 

set /a c=1 

setlocal ENABLEDELAYEDEXPANSION 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
    set /a c=c+1 
    set OUTPUT_FILE_NAME=output_!c!.txt 
    echo Output file is !OUTPUT_FILE_NAME! 
    echo %%i, !c! 
) 

endlocal 
2

Ou vous pouvez le faire sans utiliser Delay.

set /a "counter=0" 

-> votre boucle ici

do (
    statement1 
    statement2 
    call :increaseby1 
) 

:increaseby1 
set /a "counter+=1" 
0
set TEXT_T="myfile.txt" 
set /a c=1 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
    set /a c+=1 
    set OUTPUT_FILE_NAME=output_%c%.txt 
    echo Output file is %OUTPUT_FILE_NAME% 
    echo %%i, %c% 
) 
0

Utilisation de Windows 7. Ne peut pas obtenir le EnableDelayedExpansion à faire sa chose. J'ai deux fichiers de test appelés Test1.tst et Test2.tst. Je veux faire quelque chose avec seulement le premier. Les deux endroits où je les '!' ne pas résolu à la valeur. Le dernier echo imprime zéro. Voici mon code:

set /a count1=0 

setlocal EnableDelayedExpansion 
for %%x in (*.tst) do (

    if !count1! GTR 0 goto :getout 

    call :addit 

    type %%x 

    ren %%x *.xxx 

) 
@echo Almost done... 
goto :alldone 

:addit 
set /a count1=%count1% + 1 
@echo %count1% 
goto :eof 

:getout 
@echo Getting out... 
@echo !count! 

:alldone 
endlocal 
-1

Qu'en est-ce code simple, fonctionne pour moi et sur Windows 7

set cntr=1 
:begin 
echo %cntr% 
set /a cntr=%cntr%+1 
if %cntr% EQU 1000 goto end 
goto begin 

:end 
Questions connexes