如何在Windows批处理文件中按空格分割字符串?

时间:2009-11-10 10:47:04

标签: windows batch-file split

假设我有一个字符串“AAA BBB CCC DDD EEE FFF”。

如何在批处理文件中拆分字符串并检索第n个子字符串?

C#中的等价物将是

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

17 个答案:

答案 0 :(得分:38)

迭代字符串单词的三种可能的解决方案:

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

当字符串包含“*”或“?”等通配符时,版本1不起作用。

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

答案 1 :(得分:27)

请参阅HELP FOR并查看示例

或快速试试这个

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

答案 2 :(得分:27)

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

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

输出:

ddd

答案 3 :(得分:14)

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

@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

答案 4 :(得分:7)

批处理文件:

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

命令行:

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

输出:

1
2
3

答案 5 :(得分:3)

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

@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

答案 6 :(得分:2)

或Powershell为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

答案 7 :(得分:2)

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

答案 8 :(得分:2)

我最终得到了以下内容:

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%

使用此功能,您可以参数化输入和索引。确保将此代码放在bat文件中。

答案 9 :(得分:1)

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

此代码查找字符串中的第5个字符。 如果我想找到第9个字符串,我会用10替换6(添加一个)。

答案 10 :(得分:1)

这是一个基于“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

答案 11 :(得分:0)

如果有人需要使用任何定界符分割字符串并将值存储在单独的变量中,则这是我构建的脚本,

FOR /F "tokens=1,2 delims=x" %i in ("1920x1080") do (
  set w=%i
  set h=%j
)
echo %w%
echo %h%

说明:“令牌”定义了需要传递给FOR正文的哪些元素,令牌以字符“ x”分隔。 因此,在定界后,第一个和第二个令牌将传递到主体。在主体中,%i表示第一个令牌,%j表示第二个令牌。我们可以使用%k来引用第3个令牌,依此类推。

也请在cmd中键入帮助以获取详细说明。

答案 12 :(得分:0)

尝试一下:

for /F "tokens=1,2" %%a in ("hello how are you") do echo %%a %%b

通知:

"tokens"确定分割词,例如,您可以使用:

"tokens=1,2"

将显示主字符串中的2个单词,当然您应该相互使用echo %%a %%b

所以输出将是:

hello how

答案 13 :(得分:0)

这对我有用(只是我整个剧本的摘录)

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

答案 14 :(得分:0)

<强>更新 好吧,最初我将解决方案发布到一个更难的问题,用任何分隔符完全拆分任何字符串(只需更改 delims )。对不起,我阅读了比OP想要的更多公认的解决方案。我想这次我符合原来的要求:

 @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

这是一个用于拆分路径目录的批处理文件:

@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

第3版:

@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

答案 15 :(得分:0)

您可以使用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"

答案 16 :(得分:-1)

另外一个变体 - 这会查找当前路径中的程序“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