我已经将更复杂的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
这是输入文件BANG1.TXT:
HelloWorld
"Hello World"
Hello!World
"Hello!World"
生成的文件BANG2.CMD最终包含以下内容:
echo P1:[HelloWorld]
echo P1:[Hello World]
echo P1:[HelloWorld]
echo P1:[HelloWorld]
问题是,嵌入的刘海怎么了?我尝试了是否启用ENABLEDELAYEDEXPANSION。我什至尝试转义(^)输入文件中的刘海,但还是没有运气。
有什么办法可以保存它们?
谢谢。
最佳答案
问题根本就在于这里的扩展延迟。
对于延迟的扩展,感叹号用于扩展变量,但是当一行中只有一个感叹号时,它将被删除。
特别是在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