For 循环不去掉分号 (;),并且还用 bar(|) 作为 %variable% 中断,但与其他符号 (/\?^$%*=#,.:etc) 批量工作

For-loop not stripping semi-colon (;) and also breaks with bar(|) as %variable%, but works as intended with other symbols (/\?^$%*=#,.:etc) in batch

提问人:ZedCee 提问时间:4/17/2023 更新时间:4/17/2023 访问量:29

问:

在处理使用一种基于输入的自设置分隔符的脚本时,我发现将分号作为 %variable% 注入参数有点奇怪。for

令人惊讶的是,将 设置为变量似乎很少。 只是2015年3月的这个唯一的问题和单一的答案。然而,从很少的东西来看,使用 a 和一些(如另一个答案中描述的)waton 滥用循环的组合,我能够让我的 delims 填充(仅由哪些空白与)填充,并正常扩展到主循环。这很有效,但也有例外......for /F "delims=...setLocal enableDelayedExpansionforendlocal & set...!%str%:~0,1!!%~1:~0,1!

条形分隔符显然会破坏事物。我已经尝试过,但是如果不通过更改导致主循环的计数来破坏其他所有内容,我似乎无法让它们起作用。这是微不足道的,但是我不禁觉得这里的解决方案是另一个有问题的符号分号的解决方案。

分号是一只奇怪的鸭子。它们似乎正确地填充了,但即使有,也不会剥离和破坏划界。更奇怪的是,如果显式设置为 ,分号将完全按预期工作。@ECHO ONdelims=%delim%eol= "eol= delims=;"

虽然分号不是必需品,但我不禁觉得从现在开始的几步后它们可能是必需的。即使有很多替代方案,这让我非常好奇发生了什么,以及是否可以在没有大量额外代码行的情况下解决它,假装一分钟的分号对以后的功能至关重要。

脚本如下。它包含一些 readline 输入示例、预期输出以及有关结果的说明,以便于调试。Readline 输入可以直接设置,也可以在执行期间设置(取决于个人 RL 历史记录首选项)。


@ECHO OFF
@set ESC=

setLocal
if "%*" == "" (set /P strInput=Input parameters:) else set "strInput=%*"
call :delimVars strInput
endLocal
exit /B

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:delimVars [[delim]value str]...
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: input: ?~delim So long world ?~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: /~delim So long world /~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: \~delim So long world \~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: ^~delim So long world ^~delim Goodbye universe Hello multiverse
:::::::::::: ^ strips w/ interesting side effects
:: input: $~delim So long world$~delim Goodbye universe ^& Hello multiverse %=(strips)=%
:: input: %%~delim So long world%%~delim Goodbye universe ^& Hello multiverse   %=(strips)=%
:: input: ^~delim So long world ^~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: *~delim So long world *~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: =~delim So long world =~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: #~delim So long world #~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: ,~delim So long world ,~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: '~delim So long world '~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: :~delim So long world :~delim Goodbye universe ^& Hello multiverse    %=(strips)=%
:: input: |~delim So long world |~delim Goodbye universe ^& Hello multiverse    %=(breaks)=%
:::::::::::: uncertain how to escape w/o impacting parsing of other symbols
:: input: ;~delim So long world ;~delim Goodbye universe ^& Hello multiverse    %=(sticks)=%
:::::::::::: unique behaviour of semi-colon breaks delimination, even with "eol= "
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

setLocal disableDelayedExpansion
set "str=%~1"
setLocal enableDelayedExpansion
for /F %%X in ("!%~1:~0,1!") do (   %=(Param var Expansion must be used, str var blanks)=%
endLocal
set "delim=%%~X"
)
:delimVars_loop
setLocal enableDelayedExpansion
REM for /F "eol= tokens=1,* delims=;" %%A in ("!%str%!") do (       %=(Semi-colons strip)=%
for /F "eol= tokens=1,* delims=%delim%" %%A in ("!%str%!") do (     %=(Semi-colons stick)=%
    for /F "eol= tokens=1,* delims= " %%a in ("%%A") do (
        endLocal
        set "val="%%~a" "%%~b""
        )
    )
)
echo;%val%
set str=
set val=
set delim=
endLocal
exit /B
for-loop 变量 batch-file cmd 分隔符

评论

0赞 ZedCee 4/19/2023
预期的输出将是:如果无人看管,键盘问题会产生一些有趣的影响。道歉。"~delims" "So long world "

答: 暂无答案