如何在Windowsbatch file中分割string?

假设我有一个string“AAA BBB CCC DDD EEE FFF”。

我怎样才能拆分string和检索batch file中的第n个子string?

在C#中的等效将是

"AAA BBB CCC DDD EEE FFF".Split()[n] 

请参阅HELP FOR并查看示例

或者快速尝试一下

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

遍历string的三个可能的解决scheme:

版本1:

 @echo off & setlocal set s=AAA BBB CCC DDD EEE FFF for %%a in (%s%) do echo %%a 

版本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 

版本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 

当string包含通配符(如“*”或“?”)时,版本1不起作用。

版本1和3将字符'=',';' 或“,”作为单词分隔符。 这些字符与空格字符具有相同的效果。

这是唯一对我有用的代码:

 for /f "tokens=4" %%G IN ("aaa bbb ccc ddd eee fff") DO echo %%G 

输出:

 ddd 

以下代码将使用任意数量的子string拆分string:

 @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 

简单

batch file:

 FOR %%A IN (1 2 3) DO ECHO %%A 

命令行:

 FOR %A IN (1 2 3) DO ECHO %A 

输出:

 1 2 3 

以下代码将用#个分隔值拆分N个子string的string。 您可以使用任何分隔符

 @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 
 @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% ) ) 

或者一个0索引数组的Powershell。

 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 

我结束了以下几点:

 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% 

有了这个,你可以参数化input和索引。 确保把这个代码放在一个bat文件中。

 set a=AAA BBB CCC DDD EEE FFF set a=%a:~6,1% 

此代码查找string中的第5个字符。 如果我想find第9个string,我会用10replace6(添加一个)。

这是一个基于“ 函数 ”的解决scheme,它处理每个字符,直到find分隔符。

这是相对缓慢的,但至less不是一个脑筋急转弯(function部分除外)。

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

你可以使用vbscript而不是批处理(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 

用法:

 c:\test> cscript /nologo test.vbs "AAA BBB CCC" 

更新:嗯,最初我把解决scheme发布到一个更困难的问题,以任何分隔符(只是改变分隔 )的任何string的完整分割。 我比OP想要的更多地阅读被接受的解决scheme,对不起。 我觉得这个时候我遵守了原来的要求:

  @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 

另一个更好的用户界面版本:

  @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 

输出示例:

 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 

这是一个batch file来拆分path的目录:

 @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 

第二版:

 @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 

第三版:

 @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 

这适用于我(只是从我的整个脚本摘录)

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

还有一个变种 – 在当前path中查找程序“cmd.exe”并报告第一个匹配项:

 @echo off setlocal setlocal enableextensions setlocal enabledelayedexpansion set P=%PATH% :pathloop for /F "delims=; tokens=1*" %%f in ("!P!") do ( set F=%%f if exist %%f\cmd.exe goto found set P=%%g ) if defined P goto pathloop echo path of cmd.exe was not found! goto end :found echo found cmd.exe at %F% goto end :end