Supposons que j'ai une chaîne "AAA BBB CCC DDD EEE FFF".
Comment puis-je scinder la chaîne et récupérer la nième sous-chaîne dans un fichier batch?
L'équivalent en C # serait
"AAA BBB CCC DDD EEE FFF".Split()[n]
voir HELP FOR
et voir les exemples
ou essayez vite ceci
for /F %%a in ("AAA BBB CCC DDD EEE FFF") do echo %%c
Trois solutions possibles pour parcourir les mots de la chaîne:
Version 1:
@echo off & setlocal
set s=AAA BBB CCC DDD EEE FFF
for %%a in (%s%) do echo %%a
Version 2:
@echo off & setlocal
set s=AAA BBB CCC DDD EEE FFF
set t=%s%
:loop
for /f "tokens=1*" %%a in ("%t%") do (
echo %%a
set t=%%b
)
if defined t goto :loop
Version 3:
@echo off & setlocal
set s=AAA BBB CCC DDD EEE FFF
call :sub1 %s%
exit /b
:sub1
if "%1"=="" exit /b
echo %1
shift
goto :sub1
La version 1 ne fonctionne pas lorsque la chaîne contient des caractères génériques tels que '*' ou '?'.
Les versions 1 et 3 traitent les caractères comme '=', ';' ou ',' en tant que séparateurs de mots. Ces caractères ont le même effet que le caractère d'espace.
C'est le seul code qui a fonctionné pour moi:
for /f "tokens=4" %%G IN ("aaa bbb ccc ddd eee fff") DO echo %%G
sortie:
ddd
Le code suivant divisera une chaîne avec un nombre arbitraire de sous-chaînes:
@echo off
setlocal ENABLEDELAYEDEXPANSION
REM Set a string with an arbitrary number of substrings separated by semi colons
set teststring=The;rain;in;spain
REM Do something with each substring
:stringLOOP
REM Stop when the string is empty
if "!teststring!" EQU "" goto END
for /f "delims=;" %%a in ("!teststring!") do set substring=%%a
REM Do something with the substring -
REM we just echo it for the purposes of demo
echo !substring!
REM Now strip off the leading substring
:striploop
set stripchar=!teststring:~0,1!
set teststring=!teststring:~1!
if "!teststring!" EQU "" goto stringloop
if "!stripchar!" NEQ ";" goto striploop
goto stringloop
)
:END
endlocal
facile
fichier batch:
FOR %%A IN (1 2 3) DO ECHO %%A
ligne de commande:
FOR %A IN (1 2 3) DO ECHO %A
sortie:
1
2
3
Le code suivant divisera une chaîne avec N nombre de sous-chaînes avec # valeurs séparées. Vous pouvez utiliser n'importe quel délimiteur
@echo off
if "%1" == "" goto error1
set _myvar="%1"
:FORLOOP
For /F "tokens=1* delims=#" %%A IN (%_myvar%) DO (
echo %%A
set _myvar="%%B"
if NOT "%_myvar%"=="" goto FORLOOP
)
goto endofprogram
:error1
echo You must provide Argument with # separated
goto endofprogram
:endofprogram
ou Powershell pour un tableau indexé 0.
PS C:\> "AAA BBB CCC DDD EEE FFF".Split()
AAA
BBB
CCC
DDD
EEE
FFF
PS C:\> ("AAA BBB CCC DDD EEE FFF".Split())[0]
AAA
@echo off
:: read a file line by line
for /F %%i in ('type data.csv') do (
echo %%i
:: and we extract four tokens, ; is the delimiter.
for /f "tokens=1,2,3,4 delims=;" %%a in ("%%i") do (
set first=%%a&set second=%%b&set third=%%c&set fourth=%%d
echo %first% and %second% and %third% and %fourth%
)
)
Je me suis retrouvé avec ce qui suit:
set input=AAA BBB CCC DDD EEE FFF
set nth=4
for /F "tokens=%nth% delims= " %%a in ("%input%") do set nthstring=%%a
echo %nthstring%
Avec cela, vous pouvez paramétrer l'entrée et l'index. Assurez-vous de mettre ce code dans un fichier bat.
Voici une solution basée sur une " fonction " qui traite chaque caractère jusqu’à ce qu’il trouve le caractère délimiteur.
Il est relativement lent, mais au moins ce n’est pas un casse-tête (sauf pour la fonction).
:: Example #1:
set data=aa bb cc
echo Splitting off from "%data%":
call :split_once "%data%" " " "left" "right"
echo Split off: %left%
echo Remaining: %right%
echo.
:: Example #2:
echo List of paths in PATH env var:
set paths=%PATH%
:loop
call :split_once "%paths%" ";" "left" "paths"
if "%left%" equ "" goto loop_end
echo %left%
goto loop
:loop_end
:: HERE BE FUNCTIONS
goto :eof
:: USAGE:
:: call :split_once "string to split once" "delimiter_char" "left_var" "right_var"
:split_once
setlocal
set right=%~1
set delimiter_char=%~2
set left=
if "%right%" equ "" goto split_once_done
:split_once_loop
if "%right:~0,1%" equ "%delimiter_char%" set right=%right:~1%&& goto split_once_done
if "%right:~0,1%" neq "%delimiter_char%" set left=%left%%right:~0,1%
if "%right:~0,1%" neq "%delimiter_char%" set right=%right:~1%
if "%right%" equ "" goto split_once_done
goto split_once_loop
:split_once_done
endlocal & set %~3=%left%& set %~4=%right%
goto:eof
set a=AAA BBB CCC DDD EEE FFF
set a=%a:~6,1%
Ce code trouve le 5ème caractère de la chaîne . Si je voulais trouver la 9ème chaîne, je remplacerais le 6 par 10 (en ajouter un).
Cela fonctionne pour moi (juste un extrait de mon script entier)
choice /C 1234567H /M "Select an option or ctrl+C to cancel"
set _dpi=%ERRORLEVEL%
if "%_dpi%" == "8" call :helpme && goto menu
for /F "tokens=%_dpi%,*" %%1 in ("032 060 064 096 0C8 0FA 12C") do set _dpi=%%1
echo _dpi:%_dpi%:
UPDATE: Bien, au départ, j’ai posté la solution à un problème plus difficile, pour obtenir une scission complète de toute chaîne avec un délimiteur (en modifiant simplement delims). J'ai lu plus les solutions acceptées que ce que le PO voulait, désolé. Je pense que cette fois je respecte les exigences originales:
@echo off
IF [%1] EQU [] echo get n ["user_string"] & goto :eof
set token=%1
set /a "token+=1"
set string=
IF [%2] NEQ [] set string=%2
IF [%2] EQU [] set string="AAA BBB CCC DDD EEE FFF"
FOR /F "tokens=%TOKEN%" %%G IN (%string%) DO echo %%~G
Une autre version avec une meilleure interface utilisateur:
@echo off
IF [%1] EQU [] echo USAGE: get ["user_string"] n & goto :eof
IF [%2] NEQ [] set string=%1 & set token=%2 & goto update_token
set string="AAA BBB CCC DDD EEE FFF"
set token=%1
:update_token
set /a "token+=1"
FOR /F "tokens=%TOKEN%" %%G IN (%string%) DO echo %%~G
Exemples de sortie:
E:\utils\bat>get
USAGE: get ["user_string"] n
E:\utils\bat>get 5
FFF
E:\utils\bat>get 6
E:\utils\bat>get "Hello World" 1
World
Ceci est un fichier de commandes pour diviser les répertoires du chemin:
@echo off
set string="%PATH%"
:loop
FOR /F "tokens=1* delims=;" %%G IN (%string%) DO (
for /f "tokens=*" %%g in ("%%G") do echo %%g
set string="%%H"
)
if %string% NEQ "" goto :loop
2ème version:
@echo off
set string="%PATH%"
:loop
FOR /F "tokens=1* delims=;" %%G IN (%string%) DO set line="%%G" & echo %line:"=% & set string="%%H"
if %string% NEQ "" goto :loop
3ème version:
@echo off
set string="%PATH%"
:loop
FOR /F "tokens=1* delims=;" %%G IN (%string%) DO CALL :sub "%%G" "%%H"
if %string% NEQ "" goto :loop
goto :eof
:sub
set line=%1
echo %line:"=%
set string=%2
vous pouvez utiliser vbscript au lieu de batch (cmd.exe)
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
str1 = objArgs(0)
s=Split(str1," ")
For i=LBound(s) To UBound(s)
WScript.Echo s(i)
WScript.Echo s(9) ' get the 10th element
Next
usage:
c:\test> cscript /nologo test.vbs "AAA BBB CCC"
Essaye ça :
for /F "tokens=1,2" %%a in ("hello how are you") do echo %%a %%b
Remarquer :
"tokens"
détermine les mots divisés, je veux dire que vous pouvez par exemple utiliser:
"tokens=1,2"
Affiche les mots 2
de chaîne principale, Bien sûr, vous devriez utiliser mutuellement echo %%a %%b
Donc, le résultat sera:
hello how
Si quelqu'un a besoin de scinder une chaîne avec n'importe quel délimiteur et de stocker les valeurs dans des variables séparées, voici le script que j'ai construit,
FOR /F "tokens=1,2 delims=x" %i in ("1920x1080") do (
set w=%i
set h=%j
)
echo %w%
echo %h%
Explication: Les "jetons" définissent les éléments à transmettre au corps de FOR, les jetons étant délimités par le caractère "x". Ainsi, après la délimitation, les premier et deuxième jetons sont transmis au corps. Dans le corps,% i se réfère au premier jeton et% j se réfère au second jeton. Nous pouvons prendre% k pour faire référence au 3ème jeton et ainsi de suite.
Veuillez également saisir HELP FOR dans cmd pour obtenir une explication détaillée.