我对批处理不太熟练,所以我真的很挣扎。
我有两个文本文件,基本上我试图将一个文件的内容插入另一个文件。 基本上,一个文件描述对象的几何形状,另一个文件描述该几何体。
到目前为止,我的基本方法是将geomtry文件读入变量:
setlocal EnableDelayedExpansion
set LF=^
rem ** The two empty lines are necessary
set "content="
for /f "delims=" %%x in (%replace%) do (
set "content=!content!%%x"
)
echo(!content!
endlocal
然后查看我的显示程序文件以获得预定义的“标记”:
set "search=noGeometrySpecified"
然后将用一个非常长的字符串替换:content
我目前遇到的一个问题是setlocal ... endlocal
定义了某种范围(正如我所说的批处理脚本非常不确定),它不允许在我的搜索和替换中访问content
我脚本的一部分。但我不能让它与他们分享某种范围。
据我所知,我的脚本的各个部分(加载整个几何文件,以及在显示程序文件中搜索和替换)都能正常工作,但是我不能让它们互相交谈。
这是我的完整代码:
@echo off &setlocal
set "search=noGeometrySpecified"
set "replace=test_geom/\EIN.b18"
setlocal EnableDelayedExpansion
set LF=^
rem ** The two empty lines are necessary
set "content="
for /f "delims=" %%x in (%replace%) do (
set "content=!content!%%x"
)
echo(!content!
endlocal
set "textfile=index.html"
set "newfile=index-active.html"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%content%!"
echo(!line!
endlocal
))>"%newfile%"
pause
答案 0 :(得分:1)
@echo off
setlocal EnableDelayedExpansion
set "search=noGeometrySpecified"
set "replace=test_geom/\EIN.b18"
set "content="
for /f "delims=" %%x in (%replace%) do (
set "content=!content!%%x"
)
echo(!content!
set "textfile=index.html"
set "newfile=index-active.html"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
set "line=!line:%search%=%content%!"
echo(!line!
))>"%newfile%"
pause
嗯 - 似乎是希望随意洒上setlocal
和endlocal
的案例。
setlocal
需要启用delayedexpansion
(使用!var!
来提取变量的运行时值,其中%var%
提取分析时间值)。它会一直有效,直到达到endlocal
或文件结尾。
endlocal
恢复上次匹配的delayedexpansion
执行时的环境和setlocal
状态。重要的是,它支持自上次setlocal
以来所做的任何环境变化。
因此,原始代码中endlocal
之后的echo(!content!
会退回刚刚对content
的值进行的分支,因此它将恢复为原始值没有
由于您希望保留其值以便在代码的其余部分中使用,因此必须删除endlocal
。
由于delayedexpansion
已被调用且endlocal
不再删除,因此无需在for
循环内重新调用它,因此新的{{1}可以删除匹配的setlocal
。
似乎没有理由建立endlocal
变量,因为它没有被使用,所以我也处理了它。
关于在与LF
相同的行上调用setlocal
或作为单独行的个人偏好。我更喜欢单独的一行。
答案 1 :(得分:1)
正如Magoo中已解释的their answer,您错误地放置了setlocal
和endlocal
。
以下是重写脚本的另一种方法 - 解释如下:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "search=noGeometrySpecified"
set "replace=test_geom/\EIN.b18"
set "content="
for /F "usebackq delims=" %%x in ("%replace%") do (
set "item=%%x"
setlocal EnableDelayedExpansion
for /F "delims=" %%a in ("content=!content!!item!") do (
endlocal
set "%%a"
)
)
setlocal EnableDelayedExpansion
echo(!content!
endlocal
set "textfile=index.html"
set "newfile=index-active.html"
> "%newfile%" (
for /F "usebackq delims=" %%i in ("%textfile%") do (
set "line=%%i"
setlocal EnableDelayedExpansion
echo(!line:%search%=%content%!
endlocal
)
)
endlocal
pause
正如您所看到的,可以使用切换延迟扩展,但您必须考虑到endlocal
以外的任何变量都会丢失(除非您建立一些对策)。
让我们首先关注第二个for /F
循环结构:
set "textfile=index.html"
set "newfile=index-active.html"
> "%newfile%" (
for /F "usebackq delims=" %%i in ("%textfile%") do (
set "line=%%i"
setlocal EnableDelayedExpansion
echo(!line:%search%=%content%!
endlocal
)
)
在你做的事情中切换延迟扩张已经很好了。它可以避免感叹号的丢失;在扩展%%i
时,如果禁用延迟扩展,一切都很好;在扩展%%i
时,如果启用延迟扩展,感叹号会丢失(或导致其他意外结果),因为延迟扩展功能会消耗此感叹号;对于普通环境变量扩展行%var%
也是如此。
在setlocal
之后,您不需要设置变量line
,您可以立即回显被操纵的字符串;但即使您重新分配line
,也没有问题,因为line
未在endlocal
后面使用,它是在下一次循环迭代中新分配的。
现在让我们关注第一个for /F
循环结构:
set "content="
for /F "usebackq delims=" %%x in ("%replace%") do (
set "item=%%x"
setlocal EnableDelayedExpansion
for /F "delims=" %%a in ("content=!content!!item!") do (
endlocal
set "%%a"
)
)
setlocal EnableDelayedExpansion
echo(!content!
endlocal
我们再次希望通过切换延迟扩展来避免感叹号丢失。但是,这在这里很棘手,因为您需要将变量content
传递给下一个循环迭代。因此,首先将%%x
分配给临时变量item
,同时禁用延迟扩展;然后在启用延迟扩展时完成连接,但是变量content
的重新分配被延迟到endlocal
之后的稍后时间点,使用仅迭代一次的for /F
循环并且返回%%a
中的整个赋值表达式,该表达式在set
之后传递给endlocal
命令。由于在循环结构完成后禁用了延迟扩展,因此需要重新启用它以再次回显content
;当然,像echo(%content%
这样的正常扩展也可以起作用,但如果content
包含一些特殊字符,它可能会失败,所以应该避免使用。
最后,整个脚本以setlocal
命令开头,所有选项都明确指定,并以endlocal
命令结束,因此批处理脚本不依赖于调用的设置{ {1}}实例并且不会影响其环境。