目前,我有一个执行以下操作的脚本:
- 在特定文件夹中查找
- 解压缩所有 *.zip 文件
- 读取具有四列(旧名称,旧名称,新ID,新名称)的特定CSV文件 以
- 递归方式查找文件夹中的所有 *.xml 文件(示例.xml)
- 循环浏览*.xml文件,创建副本(原始bak和潜在的修改bak)
- 将旧名称替换为新名称,新名称
- 如果修改,则写入XML,删除原始文件,将bak移动到原始文件。
最后一步是我的问题所在。目前,当批处理文件读取 XML 文件时,它会丢失感叹号。导出前,示例行为:
<url><![CDATA[pdf/Post-Rec_Job Model Training.pdf]]></url>
结果为
<url><[CDATA[pdf/Post-Rec_Job Model Training.pdf]]></url>
如何保持感叹号?
在展开可能包含!
文本的 FOR 变量时不启用延迟扩展。您可以修改 :replaceCourseInfo 例程,以在循环中打开和关闭延迟扩展,而不是在例程顶部打开它。
我同意 foxidrive,我不明白修改后的变量是如何使用的,所以我把它去掉了。
:replaceCourseInfo
@echo off
setlocal
set INTEXTFILE=%~1
set OUTTEXTFILE=%~1
copy %INTEXTFILE% %INTEXTFILE%.bak
copy %INTEXTFILE% %INTEXTFILE%.original.bak
set BAKFILE=%~1.bak
if exist "%~1.bak" del /F /Q "%~1.bak"
REM Walk through XML Lines
REM @todo Need to prevent losing ! in [!CDATA[
for /F "delims=" %%U in (%~1) do (
set LINE=%%U
setlocal enabledelayedexpansion
if not "!LINE!" == "!LINE:%~2=!" (
set LINE=!LINE:%~2=%~3!
)
>> "%BAKFILE%" echo.!LINE!
endlocal
)
REM If modified, delete original, copy modified bak as new original
if NOT "%~2"=="%~3" (
del /F /Q %~1
copy %BAKFILE% %~1
)
goto:eof
我曾经使用 FOR/F 循环来修改文本文件,但获得所需结果通常很复杂。我编写了foxidrive所说的REPL.BAT脚本,现在我几乎总是使用REPL.BAT而不是FOR/F循环来修改文件。REPL.BAT更简单,更快捷。
问题是delayed expansion
- 可以解决。
您正在使用下面的代码 - 显然没有使用modified
变量。
如果字符串中存在%~2
,您的代码似乎只是简单地用%~3
替换%~2
,这可以通过 dbenham 或 SED
或 VBS search and replace feature
的REPL.BAT
来完成。
REM Walk through XML Lines
REM @todo Need to prevent losing ! in [!CDATA[
for /F "delims=" %%U in (%~1) do (
set LINE=%%U
if not "!LINE!" == "!LINE:%~2=!" (
set LINE=!LINE:%~2=%~3!
set modified=!string:%~2=%~3!
)
>> "%BAKFILE%" echo. LINE!
)
以下是替换上述代码的REPL.BAT
解决方法:
type "%~1" | REPL "%~2" "%~3" L >> "%BAKFILE%"