Question

Je programme dans des dizaines de langues depuis 20 ans, mais je n’ai jamais compris comment "POUR". travailler dans le fichier de commandes shell Windows cmd, peu importe combien j'ai essayé. Je lis

http://www.amazon.com/Windows-Administration-Command-Line- Vista / dp / 0470046163 / ref = sr_1_1? C'est-à-dire = UTF8 & amp = s = livres & amp; qid = 1241362727 & amp; sr = 8-1

http://www.ss64.com/nt/for.html

et plusieurs autres articles sur Internet mais qui restent confus et ne peuvent rien accomplir.

Quelqu'un peut-il m'expliquer de manière concise comment "POUR"? fonctionne en général?

Pour une question un peu plus spécifique, comment puis-je parcourir chaque chemin dans la variable% PATH%? J'ai essayé avec

rem showpathenv.bat
for /f "delims=;" %%g in ("%PATH%") do echo %%g

Cela ne montrerait que le premier chemin, pas tous. Pourquoi ? Qu'est-ce que je fais mal?

Était-ce utile?

La solution

Aucune des réponses ne fonctionne réellement. J'ai réussi à trouver la solution moi-même. C’est un peu bizarre, mais cela résout le problème pour moi:

echo off
setlocal enableextensions
setlocal enabledelayedexpansion
set MAX_TRIES=100
set P=%PATH%
for /L %%a in (1, 1, %MAX_TRIES%) do (
  for /F "delims=;" %%g in ("!P!") do (
    echo %%g
    set P=!P:%%g;=!
    if "!P!" == "%%g" goto :eof
  )
)

Oh! Je déteste la programmation par lots !!

Mis à jour

La solution de Mark est plus simple, mais elle ne fonctionnera pas avec les chemins contenant des espaces. Ceci est une version peu modifiée de la solution de Mark

echo off
setlocal enabledelayedexpansion
set NonBlankPath=%PATH: =#%
set TabbedPath=%NonBlankPath:;= %
for %%g in (%TabbedPath%) do (
  set GG=%%g
  echo !GG:#= !
)

Autres conseils

L'idée de Mark était bonne, mais peut-être oublié que certains chemins contiennent des espaces. Remplacement de ';' avec '" " ' au lieu de cela, couperait tous les chemins en chaînes entre guillemets.

set _path="%PATH:;=" "%"
for %%p in (%_path%) do if not "%%~p"=="" echo %%~p

Alors ici, vos chemins sont affichés.

La commande FOR dans cmd a une courbe d'apprentissage fastidieuse, notamment parce que les variables réagissent dans les instructions de () ... vous pouvez affecter n'importe quelle variable, utilisez l'option "setlocal ENABLEDELAYAYEXPANSION". instruction, et donc aussi utiliser les variables avec !! au lieu de %% (! _var!)

Je suis actuellement exclusivement en script avec cmd, pour le travail, j'ai dû apprendre tout ça:)

Vous avez la bonne idée, mais pour / f est conçu pour fonctionner sur des fichiers ou des commandes multilignes, et non sur des chaînes individuelles.

Dans sa forme la plus simple, pour est semblable au de Perl pour , ou au foreach de toutes les autres langues . Vous lui transmettez une liste de jetons et le répète, en appelant la même commande à chaque fois.

for %a in (hello world) do @echo %a

Les extensions fournissent simplement des moyens automatiques de construction de la liste des jetons. La raison pour laquelle votre code actuel n'aboutit à rien est que '; ' est le symbole par défaut de fin de ligne (commentaire). Mais même si vous le modifiez, vous devrez utiliser %% g, %% h, %% i, ... pour accéder aux jetons individuels, ce qui limitera considérablement votre fichier de traitement par lots. / p>

Le plus proche de ce que vous demandez est:

set TabbedPath=%PATH:;= %
for %%g in (%TabbedPath%) do echo %%g

Mais cela échouera pour les chemins cités contenant des points-virgules.

D'après mon expérience, pour / l et pour / r conviennent à l'extension de commandes existantes, mais sinon, pour est extrêmement limité. Vous pouvez le rendre légèrement plus puissant (et déroutant) avec le développement retardé des variables ( cmd / v: on ), mais ce n’est vraiment utile que pour les listes de noms de fichiers.

Je vous conseillerais d'utiliser WSH ou PowerShell si vous devez effectuer une manipulation de chaîne. Si vous essayez d'écrire whereis pour Windows, essayez where /? .

Je ne pouvais pas m'empêcher de jeter ceci là-bas, aussi vieux que soit ce fil de discussion ... Habituellement, lorsque vous avez besoin de parcourir chacun des fichiers de PATH, tout ce que vous voulez vraiment faire est de trouver un fichier particulier ... Si c’est le cas, ce one-liner crache le premier répertoire dans lequel se trouve votre fichier:

(ex: recherche de java.exe)

for %%x in (java.exe) do echo %%~dp$PATH:x

Je sais que c’est SUPER vieux ... mais juste pour le plaisir, j’ai décidé de tenter le coup:

@Echo OFF
setlocal
set testpath=%path: =#%
FOR /F "tokens=* delims=;" %%P in ("%testpath%") do call :loop %%P
:loop
if '%1'=='' goto endloop
set testpath=%1
set testpath=%testpath:#= %
echo %testpath%
SHIFT
goto :loop
:endloop
pause
endlocal
exit

Cela n’a pas besoin d’être compté et durera jusqu’à la fin. J'ai eu le même problème avec les espaces mais cela a traversé la variable entière. Les étiquettes de la boucle et la fonction SHIFT sont la clé.

pour / f itère une entrée par ligne, ainsi votre programme ne sortira que le premier chemin.

votre programme considère% PATH% comme une entrée sur une ligne et supprime par ; , place le premier résultat sur %% g, puis affiche le résultat %% g (premier chemin supprimé).

FOR effectue essentiellement une itération sur les " lignes " dans l'ensemble de données. Dans ce cas, une ligne contient le chemin. Le "delims =;" dit simplement qu'il se sépare en point-virgule. Si vous modifiez le corps en echo %% g, %% h, %% i, %% j, %% k , vous verrez qu'il traite l'entrée comme une seule ligne et la casse. en plusieurs jetons.

Cela fonctionne pour moi:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
@REM insure path is terminated with a ;
set tpath=%path%;
echo.
:again
@REM This FOR statement grabs the first element in the path
FOR /F "delims=;" %%I IN ("%TPATH%") DO (
  echo    %%I 
  @REM remove the current element of the path
  set TPATH=!TPATH:%%I;=!
)
@REM loop back if there is more to do. 
IF DEFINED TPATH GOTO :again

ENDLOCAL

Vous devez également utiliser la partie tokens = 1,2, ... des options autorisées par la boucle pour . Ceci fera ici ce que vous voudrez peut-être:

for /f "tokens=1,2,3,4,5,6,7,8,9,10,11,12 delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %b ^
   & echo. %a ^
   & echo. %c ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k ^
   & echo. ^
   & echo.   ...and now for some more... ^
   & echo. ^
   & echo. %a ^| %b ___ %c ... %d ^
   & dir "%e" ^
   & cd "%f" ^
   & dir /tw "%g" ^
   & echo. "%h  %i  %j  %k" ^
   & cacls "%f")

Cet exemple traite uniquement les 12 premiers jetons (= répertoires de% path%). Il utilise une énumération explicite de chacun des jetons utilisés. Notez que les noms de jeton sont sensibles à la casse:% a est différent de% A.

Pour enregistrer des chemins contenant des espaces, entourez tout % x avec des guillemets tels que celui-ci "% i". Je ne l'ai pas fait ici où je fais seulement écho aux jetons.

Vous pouvez aussi faire comme ceci:

for /f "tokens=1,3,5,7-26* delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %c ^
   & echo. %b ^
   & echo. %a ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k )

Celui-ci ignore les jetons 2, 4, 6 et utilise un petit raccourci (" 7-26 ") pour nommer les autres. Notez comment% c,% b,% a sont traités en ordre inverse cette fois-ci et comment ils "signifient" maintenant différents jetons, par rapport au premier exemple.

Ce n’est donc certainement pas l’explication concise que vous avez demandée. Mais peut-être que les exemples aident à clarifier un peu mieux maintenant ...

Voici un bon guide:

commande FOR / F - Loop: sur un ensemble de fichiers.

commande FOR / F - Loop: par rapport aux résultats d'une autre commande.

Commande FOR - Loop: toutes les options Fichiers, Répertoire, Liste.

[Tout le guide (commandes Windows XP):

http://www.ss64.com/nt/index.html

Modifier: Désolé, le lien figurait déjà dans le PO, car il m'est apparu comme faisant partie du lien Amazon.

Cela fonctionne pour moi, essayez-le.

for /f "delims=;" %g in ('echo %PATH%') do echo %g%

Cela fonctionne pour moi, essayez-le.

pour / f "jetons = * delims =;"; % g in ('echo% PATH%') fait écho% g%

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top