【发布时间】:2010-12-14 23:46:44
【问题描述】:
假设我有一个字符串“AAA BBB CCC DDD EEE FFF”。
如何在批处理文件中拆分字符串并检索第 n 个子字符串?
C# 中的等价物是
"AAA BBB CCC DDD EEE FFF".Split()[n]
【问题讨论】:
标签: windows batch-file split
假设我有一个字符串“AAA BBB CCC DDD EEE FFF”。
如何在批处理文件中拆分字符串并检索第 n 个子字符串?
C# 中的等价物是
"AAA BBB CCC DDD EEE FFF".Split()[n]
【问题讨论】:
标签: windows batch-file split
查看HELP FOR 并查看示例
或快速尝试一下
for /F %%a in ("AAA BBB CCC DDD EEE FFF") do echo %%c
【讨论】:
您可以使用 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"
【讨论】:
简单
批处理文件:
FOR %%A IN (1 2 3) DO ECHO %%A
命令行:
FOR %A IN (1 2 3) DO ECHO %A
输出:
1
2
3
【讨论】:
以下代码将使用任意数量的子字符串拆分字符串:
@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
【讨论】:
ENABLEDELAYEDEXPANSION 并将所有 ! 替换为 %,它似乎也可以正常工作。或者您是否特别需要该设置?
set a=AAA BBB CCC DDD EEE FFF
set a=%a:~6,1%
此代码查找字符串中的第 5 个字符。 如果我想找到第 9 个字符串,我会将 6 替换为 10(加一个)。
【讨论】:
这是唯一对我有用的代码:
for /f "tokens=4" %%G IN ("aaa bbb ccc ddd eee fff") DO echo %%G
输出:
ddd
【讨论】:
/f "tokens..,它在 Windows 10 上不起作用。
或 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
【讨论】:
以下代码将拆分一个包含 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
【讨论】:
遍历字符串单词的三种可能解决方案:
版本 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 将字符处理为 '='、';'或 ',' 作为单词分隔符。这些字符与空格字符的作用相同。
【讨论】:
set /p s=<StringInFile.txt 将字符串从文件中取出,然后使用set t=%s%
set t=%%b 到底在做什么?它从何而来?对不起,我不明白。请解释一下?谢谢。
%%b 包含剩余的单词。 set t=%%b 从变量 t 中删除第一个单词。 “for”循环每次只执行一次,因为指定了/f 参数,而("%t%") 只是一行文本。 “goto :loop”是每个单词执行一次的实际循环。
@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%
)
)
【讨论】:
这是一个基于“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
【讨论】:
更新: 好吧,最初我发布了一个更困难问题的解决方案,用任何分隔符完全拆分任何字符串(只需更改 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
第三版:
@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%:
【讨论】:
我最终得到了以下结果:
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 文件中。
【讨论】:
另一种变体 - 在当前路径中查找程序“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
【讨论】:
如果有人需要使用任何分隔符拆分字符串并将值存储在单独的变量中,这是我构建的脚本,
FOR /F "tokens=1,2 delims=x" %i in ("1920x1080") do (
set w=%i
set h=%j
)
echo %w%
echo %h%
解释:'tokens' 定义了需要传递给 FOR 主体的元素,token 由字符 'x' 分隔。 所以在定界之后,第一个和第二个token被传递给body。在正文中,%i 指的是第一个标记,%j 指的是第二个标记。我们可以用 %k 来引用第三个令牌等等..
请在cmd中同时输入HELP FOR以获取详细解释。
【讨论】: