需要帮助!处理批处理文件,该文件将替换文件夹中的一堆文本文件中的一组字符。我找到了会这样做的代码。但它只适用于一个文件。有没有办法可以为文件夹中的所有文件执行此操作。文件夹中总共有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%
答案 0 :(得分:1)
如果你想要一个纯批处理解决方案,那么最简单的方法是将代码封装在一个子程序中,该子程序将文件名作为参数,并在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
。
答案 1 :(得分:0)
由于您需要做的只是替换现有文件中的文字,因此请使用FART之类的专门用于执行此操作的工具:
FART -r "C:\Data\Directory\*.txt" "OldText" "NewText"
-r
开关表示处理提供的目录和子文件夹中的所有txt
个文件。
请注意,您可以添加-i
开关,以便在搜索时忽略大小写。