2016-08-12 1 views
1

Alors, quand je lance ce code:Lot: indirection variable: obtenir la valeur d'une variable par nom construit dynamiquement

@echo off 
setlocal enabledelayedexpansion 

set lstFolders= First Second 

set intCounter=0 
for %%i in (!lstFolders!) do (
    set /a intCounter += 1 
    set strFlder=%%i 
    set strFolder!intCounter!=!strFlder! 
    echo %%i 
    echo !strFlder! 
    echo !strFolder%intCounter%! 
    echo !strFolder1! 
    echo !strFolder2! 
) 

:End 
pause 
endlocal 

Il en résulte avec ceci:

First 
First 
ECHO is off. 
First 
ECHO is off. 
Second 
Second 
ECHO is off. 
First 
Second 

Pourquoi ne pas permettre moi de faire écho à la variable créer avec le format: !strFolder%intCounter%!? Existe-t-il une autre façon de référencer cette variable et d'obtenir les données qui s'y trouvent?

+1

Bien que pas une copie exacte, parce que la question demande également de this au sujet des variables _creating_ indirectement (et se concentre sur l'utilisation de l'évaluation retardée), la question suivante est étroitement liée: http://stackoverflow.com/q/9369874/45375 – mklement0

Répondre

0

caveat: Le code ci-dessous ne fonctionne avec les valeurs de la liste (les jetons de %lstFolders% tels que First) que:

  • ne contiennent ni espaces
  • ni aucun des caractères suivants .: & | < > "

Une approche en boucle différente serait nécessaire pour gérer de tels cas.

@echo off 
setlocal enabledelayedexpansion 

set "lstFolders=First Second" 

set intCounter=0 
for %%i in (%lstFolders%) do (
     rem Increment the counter 
    set /a intCounter += 1 
     rem Echo the loop variable 
    echo #!intCounter!=%%i 
     rem Set variable strFolder<intCounter> to the loop variable's value 
    set "strFolder!intCounter!=%%i" 
     rem Echo the variable created using variable indirection with for /f ('...') 
    for /f "delims=" %%v in ('echo "%%strFolder!intCounter!%%"') do set "thisFolder=%%~v" 
    echo %%thisFolder%% ^(via %%strFolder!intCounter!%%^)=!thisFolder! 
) 

Exécution des rendements supérieurs:

#1=First 
%thisFolder% (via %strFolder1%)=First 
#2=Second 
%thisFolder% (via %strFolder2%)=Second 

Qu'est-ce que vous cherchez est indirection variables:

  • Pendant que vous pouvez définir une variable indirectement (par un nom que vous construire dynamiquement à partir de la valeur de une autre variable), par exemple,
    • set "strFolder!intCounter!=%%i", avec !intCounter! ayant une valeur de 1, définit correctement la variable strFolder1 à la valeur de %%i) ,
  • vous ne peut pas obtenir Apprécions une variable de cette façon; vous besoin d'une étape d'évaluation supplémentaire , que for /f ... ('echo ...') peut fournir.:

    • for /f "delims=" %%v in ('echo "%%strFolder!intCounter!%%"') do ... analyse le résultat de la commande entre guillemets simples (echo ...) et affecte le résultat dans son ensemble (delims=) à la variable %%v
      (%%~v supprime les guillemets doubles entourant, qui ont été ajoutés dans le echo argument pour rendre la commande gérer les métacaractères shell tels que & | < > correctement).

    • %%strFolder!intCounter!%%immédiatement évalue strFolder!intCounter! à strFolder1, si !intCounter! est 1, qui, grâce à l'enfermer doublé% cas, se termine comme littérale%strFolder1%, qui est ce que la commande echo voit quand il est exécuté par la commande for, l'amenant à évaluer la référence de la variable et à l'étendre à sa valeur.

+1

Oui , Je viens de mettre votre code dans un fichier batch et l'ai couru, regardé par-dessus, et maintenant je l'obtiens. Merci beaucoup, c'est une aide énorme. – jrwygal

1

Comme @ mklement0 déjà dit, vous avez besoin d'une étape d'évaluation supplémentaire.
Mais malgré l'utilisation de echo "%%strFolder!intCounter!%%", je recommande une expansion retardée.
Étant donné que l'expansion retardée est insensible à tout contenu, echo "%%strFolder... échouera avec du contenu contenant des guillemets ou des points d'exclamation. Le doublement des guillemets évite des problèmes avec le caractère eol de la boucle FOR/F. Le double des guillemets évite les problèmes avec le caractère eol de la boucle FOR/F.