web-dev-qa-db-fra.com

Comment diviser une chaîne par des espaces dans un fichier batch Windows?

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]
51
Cheeso

voir HELP FOR et voir les exemples

ou essayez vite ceci

 for /F %%a in ("AAA BBB CCC DDD EEE FFF") do echo %%c
28
PA.

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.

33

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
26
Scott E

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
14
Dave

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
7
capdragon

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
3
user2637808

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
2
ecciethetechie
@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% 
    )
)
2
Pello X

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.

2
Bruno

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
1
blackwell
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).

1
Jon

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%:
0
gonzalezea

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
0
carlos_lm

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"
0
ghostdog74

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
0

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.

0
p_champ