批处理问题:无法遍历字符串变量
Batch probblem: Cant iterate through string variable
为了完成这个简单的任务,我已经疯狂了 2 天:遍历带有分隔符的 5 行字符串(或具有相同内容的文件)。找到定界符后,我希望将该行写入文件,然后为 cr/lf 表示添加 echo,并对下一段字符串进行下一次迭代。
出于学术目的,我重新创建了这样的代码:
@echo off
setlocal EnableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
for /f "tokens=* delims=+" %%i in ("%s%") do (
echo %%i>>test.txt
echo. >>test.txt
)
pause
输出如下:
A A A+B B B+C C C+D D D+E E E+
newline
当我想要这个时
A A A
B B B
C C C
D D D
E E E
当我将标记更改为 1 或 2 时,它 returns 正确的行
如何获取这些子字符串并将它们写入文件?为什么令牌不起作用?
我试图将其放入另一个循环并将令牌编号作为 !j! 传递,但它不起作用。我也想到了一些 goto,但认为这是一种不好的做法。
使用“Tokens=*”,您请求 for-loop 到 return 它在第一个参数中找到的所有内容,并且在这样做时完全忽略 delims-clause.
你要的是前5个token,用分隔符“+”隔开。
for /f "tokens=1-5 delims=+" %%i in ("%s%") do >>test.txt (
echo %%i
echo %%j
echo %%k
echo %%l
echo %%m
echo.
)
以下批处理代码片段中的子例程 split_supplied_line
应该可以解决 (almost) 任意数量的子字符串和 (almost) 任何定界符。不管是否有结尾分隔符。
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
rem set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%" without trailing %dlm%
call :split_supplied_line "%s%" "%dlm%" "72351984test.txt"
goto :eof
:split_supplied_line
set "restofline=%~1" 1st parameter: line to split
set "delims=%~2" 2nd parameter: delimiter character
set "tofile=%~3" 3rd parameter: file where to write
:in_split_supplied_line
call set "noplusline=%restofline:%delims%=%"
if "%noplusline%"=="%restofline%" (
SETLOCAL EnableDelayedExpansion
echo !restofline!>>"%tofile%"
ENDLOCAL
goto :eof
)
for /f "tokens=1,* delims=%delims%" %%i in ("%restofline%") do (
echo %%i>>"%tofile%""
set "restofline=%%j"
)
if ""=="%restofline%" goto :eof
goto :in_split_supplied_line
输出:2>nul del 72351984test.txt & .\SO351984.bat & type 72351984test.txt
A A A
B B B
C C C
D D D
E E E
但是,还有一种更棘手的方法(不幸的是,尾随定界符会在输出中添加一个空行):
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
rem set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%" without trailing %dlm%
>72351984test.txt (echo %s:+=&echo.%)
ENDLOCAL
goto :eof
输出:2>nul del 72351984test.txt & .\SO351984a.bat & type 72351984test.txt
A A A
B B B
C C C
D D D
E E E
为了完成这个简单的任务,我已经疯狂了 2 天:遍历带有分隔符的 5 行字符串(或具有相同内容的文件)。找到定界符后,我希望将该行写入文件,然后为 cr/lf 表示添加 echo,并对下一段字符串进行下一次迭代。
出于学术目的,我重新创建了这样的代码:
@echo off
setlocal EnableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
for /f "tokens=* delims=+" %%i in ("%s%") do (
echo %%i>>test.txt
echo. >>test.txt
)
pause
输出如下:
A A A+B B B+C C C+D D D+E E E+
newline
当我想要这个时
A A A
B B B
C C C
D D D
E E E
当我将标记更改为 1 或 2 时,它 returns 正确的行
如何获取这些子字符串并将它们写入文件?为什么令牌不起作用?
我试图将其放入另一个循环并将令牌编号作为 !j! 传递,但它不起作用。我也想到了一些 goto,但认为这是一种不好的做法。
使用“Tokens=*”,您请求 for-loop 到 return 它在第一个参数中找到的所有内容,并且在这样做时完全忽略 delims-clause.
你要的是前5个token,用分隔符“+”隔开。
for /f "tokens=1-5 delims=+" %%i in ("%s%") do >>test.txt (
echo %%i
echo %%j
echo %%k
echo %%l
echo %%m
echo.
)
以下批处理代码片段中的子例程 split_supplied_line
应该可以解决 (almost) 任意数量的子字符串和 (almost) 任何定界符。不管是否有结尾分隔符。
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
rem set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%" without trailing %dlm%
call :split_supplied_line "%s%" "%dlm%" "72351984test.txt"
goto :eof
:split_supplied_line
set "restofline=%~1" 1st parameter: line to split
set "delims=%~2" 2nd parameter: delimiter character
set "tofile=%~3" 3rd parameter: file where to write
:in_split_supplied_line
call set "noplusline=%restofline:%delims%=%"
if "%noplusline%"=="%restofline%" (
SETLOCAL EnableDelayedExpansion
echo !restofline!>>"%tofile%"
ENDLOCAL
goto :eof
)
for /f "tokens=1,* delims=%delims%" %%i in ("%restofline%") do (
echo %%i>>"%tofile%""
set "restofline=%%j"
)
if ""=="%restofline%" goto :eof
goto :in_split_supplied_line
输出:2>nul del 72351984test.txt & .\SO351984.bat & type 72351984test.txt
A A A
B B B
C C C
D D D
E E E
但是,还有一种更棘手的方法(不幸的是,尾随定界符会在输出中添加一个空行):
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
rem set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%" without trailing %dlm%
>72351984test.txt (echo %s:+=&echo.%)
ENDLOCAL
goto :eof
输出:2>nul del 72351984test.txt & .\SO351984a.bat & type 72351984test.txt
A A A
B B B
C C C
D D D
E E E