Nombre de limites de jetons dans une commande FOR dans un script de lot Windows

J’essayais de traiter un fichier texte dans un script batch Windows et j’ai rencontré quelque chose qui ressemble à une limitation à 31 jetons dans une boucle FOR. J’ai isolé le problème dans le code ci-dessous:

@ECHO OFF SET DATA=01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 FOR /F "tokens=31* delims= " %%i IN ("%DATA%") DO ( ECHO [%%i] ECHO [%%j] ) ECHO. FOR /F "tokens=32* delims= " %%i IN ("%DATA%") DO ( ECHO [%%i] ECHO [%%j] ) 

La sortie est la suivante:

 [31] [32 33 34 35] [01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35] [%j] 

et je m’attendais à ça:

 [31] [32 33 34 35] [32] [33 34 35] 

En espérant que je n’ai pas fait quelque chose de mal, je n’ai pas trouvé cette limitation documentée dans l’aide de la commande FOR. J’utilise Windows XP. Connaissez-vous une solution de contournement pour cela, en plus de couper des parties des données?

Je vous remercie.

Je suis venu avec une solution. Ce n’est pas élégant, mais cela résout mon problème. Lorsque l’interpréteur de ligne de commande ne peut pas aller plus loin avec les jetons, je passe le remaniement des données à une commande CALL: label. Voici un exemple:

 @ECHO OFF SET DATA=01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 FOR /F "tokens=1,31* delims= " %%i IN ("%DATA%") DO ( ECHO 1st token: %%i ECHO 31th token: %%j CALL :processdatatokens32-62 %%k ) :processdatatokens32-62 SET DATA=%* FOR /F "tokens=1,31* delims= " %%i IN ("%DATA%") DO ( ECHO 32nd token: %%i ECHO 62th token: %%j CALL :processdatatokens63-83 %%k ) GOTO :EOF :processdatatokens63-83 SET DATA=%* FOR /F "tokens=1,31* delims= " %%i IN ("%DATA%") DO ( ECHO 63th token: %%i ECHO 93th token: %%j ) GOTO :EOF 

La sortie est la suivante:

  1st token: 01 31th token: 31 32nd token: 32 62th token: 62 63th token: 63 93th token: 93 

De for /? :

% i est explicitement déclaré dans l’instruction for et les% j et% k sont déclarés implicitement via l’option tokens =. Vous pouvez spécifier jusqu’à 26 jetons via les jetons = ligne, à condition que cela n’entraîne pas une tentative de déclaration d’une variable supérieure à la lettre “z” ou “Z”. Rappelez-vous que les variables FOR sont à une seule lettre, sensibles à la casse, globales et que vous ne pouvez pas avoir plus de 52 actifs à la fois.

Un jeton est la plus petite unité de syntaxe qui compte comme un bloc. Et une ligne de commande par lot dans Windows 95/98 / ME a une limite maximale de 64 jetons. Plus, et la ligne de commande générera une erreur de Bad command or file name .

c’est pourquoi vous êtes probablement limité à 31 dans DATA.

Il existe plusieurs façons de parcourir le tableau de données:

 @ECHO OFF setlocal ENABLEDELAYEDEXPANSION SET DATA=01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 for /l %%a in (0,3,150) do @echo %%a data: !data:~%%a,2! 

Cela est possible uniquement à cause des deux variables de caractère du tableau% DATA%. Comme vous le verrez, la limite est maintenant de 99 caractères, au lieu de 31. Lorsque vous atteignez le 100ème et au-delà, le nombre est tronqué.

Rob

J’ai créé une fonction de machine à écrire pour le lot (juste pour le plaisir) et j’ai également rencontré cette limitation. Ci-dessous une version simplifiée pour vous montrer comment j’ai résolu le problème. Vous pouvez utiliser jusqu’à 8 191 caractères, y compris des séparateurs d’espace, lorsqu’ils sont exécutés à partir de la ligne de commande. Lorsque vous utilisez une variable, la longueur maximale est de 32 767.

 @echo off ::############################################################################# :_typeWriter   ::############################################################################# :: :: Copyleft Denny Lenselink 2018 :: %= Set local environment =% ( call ) & 2>nul setlocal EnableDelayedExpansion || exit /b 99 :: Set vars set "_CNT=0" && set "_LEN=0" && set "_STR= %~1" && set "_TOT=0" :_typeWriter_Loop set /a "_CNT+=1" :: 31 tokens limit fix. Cut the used part of the ssortingng and set counter to 1 if !_CNT! equ 32 ( set "_CNT=1" && set "_STR=!_STR:~%_TOT%!" && set "_TOT=0" ) :: Go through ssortingng (seeking words) for /f "tokens=%_CNT% delims= " %%* in ( "%_STR%" ) do ( :: Set word var set "_WRD=#%%*" :: Calculate word length for /l %%I in ( 12, -1, 0 ) do ( set /a "_LEN|=1<<%%I" for %%J in ( !_LEN! ) do ( if "!_WRD:~%%J,1!"=="" set /a "_LEN&=~1<<%%I" ) ) :: Strip first char (used before to calculate correct word length) set "_WRD=!_WRD:~1!" :: Count chars including spaces set /a "_TOT=!_TOT!+!_LEN!+1" :: Type word or use echo  

Execute: C: \ Temp> typewriter "this is a test that works"

Résultat:

 this is a test that works 

Changer la ligne Pour echo !_WRD! aura pour résultat:

 this is a test that works