CMD文件中缺少感叹号的奇怪案例

Nei*_*her 5 windows cmd batch-file

我已经将更复杂的 CMD 脚本缩减为基本要素。它逐行读取输入文件,取消引用(如果引用)并将其写出到另一个 CMD 文件。

问题是,如果输入文件包含感叹号(! 或 bang),则字符会在行的某处被删除。

这是 CMD 脚本,BANG1.CMD:

@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
if exist bang2.cmd del bang2.cmd
for /f "tokens=*" %%a in (bang1.txt) do call :doit1 %%a
exit /b

:doit1
set P1=%1
if %P1%. EQU . exit /b
call :unquotex P1 %P1%
echo>>bang2.cmd echo P1:[%P1%]
exit /b

:unquotex
set X=%2
set Q=%X:~0,1%
if "!Q!" EQU ^""" SET X=!X:~1,-1!
set %1=%X%
exit /b
Run Code Online (Sandbox Code Playgroud)

这是输入文件 BANG1.TXT:

HelloWorld
"Hello World"
Hello!World
"Hello!World"
Run Code Online (Sandbox Code Playgroud)

生成的文件 BANG2.CMD 最终包含以下内容:

echo P1:[HelloWorld]
echo P1:[Hello World]
echo P1:[HelloWorld]
echo P1:[HelloWorld]
Run Code Online (Sandbox Code Playgroud)

问题是,嵌入式刘海怎么了?我尝试过使用和不使用 ENABLEDELAYEDEXPANSION。我什至尝试转义 (^) 输入文件中的刘海,但仍然没有运气。

有什么办法可以保存它们吗?

谢谢。

jeb*_*jeb 5

问题根本在于这里的扩展延迟。
延迟扩展是使用感叹号来扩展变量,但当一行中只有一个感叹号时,感叹号将被删除。

特别是在 FOR /F 循环中,延迟扩展很难处理,因为 FOR 参数的扩展直接受延迟扩展的影响。唯一的解决办法是暂时禁用它。
下一个问题是CALL,您无法传输内容CALL(而不破坏它)。
最好通过引用(仅变量名)传递变量,然后在被调用函数中获取内容。
代码中的最后一个问题是百分比扩展,不要使用它们

当启用延迟扩展时,由于延迟扩展是在百分比扩展之后评估的,因此扩展的行将通过延迟扩展进行第二次扩展。
样本。假设var的内容是Bang!

echo %var%扩展为,Bang!但延迟扩展将计算Bang!Bang

echo !var!您一起简单获得Bang!

@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
if exist bang2.cmd del bang2.cmd
for /f "tokens=*" %%a in (bang1.txt) do (  
  setlocal DisableDelayedExpansion
  set "line=%%a"
  setlocal EnableDelayedExpansion
  call :doit1 line
  endlocal
  endlocal
)
exit /b

:doit1
set "P1=!%1!"
if "!P1!" EQU "" exit /b
call :unquotex P1
echo>>bang2.cmd echo P1:[!P1!]
exit /b

:unquotex
set "param=!%~1!"
if "!param:~0,1!" == ^""" (
    set "param=!param:~1,-1!"
)
set "%1=!param!"
exit /b
Run Code Online (Sandbox Code Playgroud)