需要帮忙 !处理批处理文件,它将替换文件夹中一堆文本文件中的一组字符。我找到了可以做到的代码。但这仅适用于一个文件。有没有一种方法可以对文件夹中的所有文件执行此操作。该文件夹中总共有1000个文件。我正在使用Windows 7操作系统。附加我在一个文件中找到的代码。
谢谢哈里
@echo off
setlocal enabledelayedexpansion
set INTEXTFILE=Replace_string.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=Apple
set REPLACETEXT=Mango
set SEARCHTEXT=Cat
set REPLACETEXT=Dog
set OUTPUTLINE=
for /f "tokens=1,* delims=¶" %%A in ( '"findstr /n ^^ %INTEXTFILE%"') do (
SET string=%%A
for /f "delims=: tokens=1,*" %%a in ("!string!") do set "string=%%b"
if "!string!" == "" (
echo.>>%OUTTEXTFILE%
) else (
SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
echo !modified! >> %OUTTEXTFILE%
)
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%
如果要使用纯批处理解决方案,那么最简单的方法是将代码封装在一个以文件名作为参数的子例程中,然后从用于循环访问文件名的FOR循环中调用该例程。这是一种通用方法,可用于要针对文件夹中的文件迭代运行的任何代码。
代码的最终结果不会创建或重命名任何文件夹,因此简单的FOR是可以安全使用的。但是,如果您的代码创建或重命名了文件夹,则FOR循环也可以处理新创建或重命名的文件。可以通过将FOR / F与DIR / B命令一起使用来解决。
注-我从代码中消除了死的(未使用的)变量。
@echo off
setlocal enabledelayedexpansion
pushd "c:\path\to\your\folder\containing\files\to\modify"
for %%F in (*.txt) do call :replace "%%F"
exit /b
:replace
set INTEXTFILE=%1
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=Cat
set REPLACETEXT=Dog
for /f "tokens=1,* delims=¶" %%A in ( '"findstr /n ^^ %INTEXTFILE%"') do (
SET string=%%A
for /f "delims=: tokens=1,*" %%a in ("!string!") do set "string=%%b"
if "!string!" == "" (
echo.>>%OUTTEXTFILE%
) else (
SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
echo !modified! >> %OUTTEXTFILE%
)
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%
exit /b
但是代码存在许多限制和效率低下的地方,还有很大的改进空间。
局限性:
输入和输出线的长度必须少于8191字节。
搜索忽略大小写
搜索字符串不能包含=
或开头~
,*
或!
替换字符串不能包含 !
包含的!
行将被破坏,因为展开时启用了延迟%%A
扩展。这可以通过策略性地切换循环内的延迟扩展打开和关闭来解决。
龙头:
将从所有行,因为连续的分隔符作为一个分隔符对待被剥离。
如果搜索词包含替换将被破坏%%a
或%%b
或%%A
。可以通过将搜索和替换项转移到FOR变量来避免这种情况。
搜索和/或替换词中的某些字符可能会引起问题或需要复杂的转义序列。通过在环境变量中获取所需的字符串(可能仍需要转义序列),然后使用延迟扩展和FOR / F将值传输到FOR变量,可以简化此操作。
在有些模糊的情况下ECHO.
可能会失败。保证可以使用的唯一安全变体是ECHO(
。
如果替换字符串为空,则替换后非空行可能变为空,并且由于ECHO.
未ECHO(
使用或未使用空行,因此不会正确输出空行。
效率低下/其他问题
对输出的每一行都执行重定向,这很慢。更好(更快)在循环外重定向一次。
DEL / RENAME对可以由单个MOVE命令代替
CALL相对较慢。如果您想要最快的解决方案,最好最大程度地减少CALL的使用。但是有时候这是无法避免的。
我更喜欢使用临时文件名作为原始名称的派生词。我通常.new
在原始名称后附加扩展名,因此“ original.txt”变为“ original.txt.new”
下面是经过高度优化的代码,除了上面的前四个要点之外,其他所有内容都已解决。如果要使用FOR / F读取文件,它与纯批处理一样强大和高效。
@echo off
setlocal disableDelayedExpansion
pushd "c:\path\to\your\folder\containing\files\to\modify"
set "find=Cat"
set "repl=Dog"
setlocal enableDelayedExpansion
for /f delims^=^ eol^= %%S in ("!find!") do (
for /f delims^=^ eol^= %%R in ("!repl!") do (
endlocal
for %%F in (*.txt) do (
for /f "delims=" %%L in ('findstr /n "^" "%%F"') do (
set "ln=%%L"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
if defined ln set "ln=!ln:%%S=%%R!"
echo(!ln!
endlocal
)
) >"%%F.new" & move /y "%%F.new" "%%F" >nul
)
)
popd
以上需要大量经验和奥秘知识才能发展。即使完成所有工作,它仍然具有以下限制。
输入和输出线的长度必须少于8191字节。
搜索忽略大小写
搜索字符串不能包含=
或开头~
,*
或!
替换字符串不能包含 !
要消除这些限制,就需要大量的缓慢甚至难以理解的代码。几乎不值得。
这就是为什么我放弃使用纯批处理进行文本处理的原因,我开发了JREPL.BAT来为Windows命令环境提供强大的正则表达式文本处理功能。JREPL是纯脚本(混合JScript /批处理),可从XP开始在任何Windows计算机上本地运行。
JREPL使解决方案变得如此简单,可以轻松地在命令行上直接运行,而无需任何批处理文件。
pushd "c:\your\path\with\files\to\be\modified"
for %F in (*.txt) do call jrepl "Cat" "Dog" /l /f "%F" /o -
popd
搜索区分大小写。/i
如果希望搜索忽略大小写,则可以添加选项。如果在批处理脚本中使用命令%F
,%%F
请将更改为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句