批处理前台:无法通过字符串变量迭代

发布于 2025-01-31 10:40:22 字数 757 浏览 3 评论 0原文

我要完成这项简单的任务2天,我将疯狂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时,它会返回正确的行

如何获取这些子字符串并将其写入文件?为什么令牌不起作用?

我试图将其放入另一个循环中,并将其传递给!j!,但它不起作用。我也想到了一些Goto,但认为这是一种不好的做法。

I'm going crazy for 2 days with this simple task: iterate through a 5 line string with delimiters (or a file with the same content). After I find a delimiter symbol I expect to write that line to the file, then add echo for a cr/lf representation and do next iteration for a next piece of string.

For academic purposes I recreate the code like that:

@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

The output is like:

A A A+B B B+C C C+D D D+E E E+
newline

When I want this

A A A
B B B
C C C
D D D
E E E

When I change token to 1 or 2 it returns the correct line

How to get those sub strings and write them to the file? Why tokens don't work?

I tried to put this into another loop and pass token number as !j!, but it doesn't work. I also thought of a few goto but think it's a bad practice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何以笙箫默 2025-02-07 10:40:22

subroutine split_supplied_line在以下批处理代码段中应为(几乎)提供任何数量的substrings和(几乎)任何定界符。不管是否有尾随的定界符。

@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& 。\ so \ 72351984.bat&类型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

output 2> nul del 72351984test.txt.txt & 。\ so \ 72351984a.bat&类型72351984Test.txt

A A A
B B B
C C C
D D D
E E E

The subroutine split_supplied_line in the following batch code snippet should do the trick for (almost) any number of substrings and (almost) any delimiter. No matter whether there is a trailing delimiter.

@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

Output: 2>nul del 72351984test.txt & .\SO\72351984.bat & type 72351984test.txt

A A A
B B B
C C C
D D D
E E E

However, there is a more tricky approach (unfortunately, a trailing delimiter adds a blank line into the output):

@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

Output: 2>nul del 72351984test.txt & .\SO\72351984a.bat & type 72351984test.txt

A A A
B B B
C C C
D D D
E E E
只涨不跌 2025-02-07 10:40:22

使用“ Tokens =*”,您请求For-loop将其找到的所有内容都返回到第一个参数中,并且在这样做时,请完全忽略Delims-Clause。

您想要的是前5个令牌,由定界符“+”隔开。

for /f "tokens=1-5 delims=+" %%i in ("%s%") do  >>test.txt (
echo %%i
echo %%j
echo %%k
echo %%l
echo %%m
echo.

With "Tokens=*" you request the for-loop to return everything it finds into the first parameter, and in doing so completely ignore the delims-clause.

What you want is the first 5 tokens, separated by delimiter "+".

for /f "tokens=1-5 delims=+" %%i in ("%s%") do  >>test.txt (
echo %%i
echo %%j
echo %%k
echo %%l
echo %%m
echo.

)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文