Batch file 替换windows文件夹中一组文本文件中的字符串
需要帮助!处理一个批处理文件,该批处理文件将替换文件夹中一组文本文件中的一组字符。我已经找到了可以这样做的代码。但它只适用于一个文件。是否有一种方法可以对文件夹中的所有文件执行此操作。文件夹中总共有1000个文件。我使用的是Windows7操作系统。将我找到的代码附加到一个文件的位置 谢谢 哈利Batch file 替换windows文件夹中一组文本文件中的字符串,batch-file,Batch File,需要帮助!处理一个批处理文件,该批处理文件将替换文件夹中一组文本文件中的一组字符。我已经找到了可以这样做的代码。但它只适用于一个文件。是否有一种方法可以对文件夹中的所有文件执行此操作。文件夹中总共有1000个文件。我使用的是Windows7操作系统。将我找到的代码附加到一个文件的位置 谢谢 哈利 由于您只需替换现有文件中的文本,因此请使用专门为此设计的工具: FART -r "C:\Data\Directory\*.txt" "OldText" "NewText" -r开关指示处理所提供目录
由于您只需替换现有文件中的文本,因此请使用专门为此设计的工具:
FART -r "C:\Data\Directory\*.txt" "OldText" "NewText"
-r
开关指示处理所提供目录和子文件夹中的所有txt
文件
请注意,您可以添加
-i
开关以在搜索时忽略大小写。如果您想要纯批处理解决方案,那么最简单的方法是将代码封装在以文件名为参数的子例程中,并从迭代文件名的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
,则替换项将损坏。这可以通过将搜索和替换项转移到FOR变量来避免%%a
- 搜索和/或替换术语中的某些字符可能会导致问题或需要复杂的转义序列。通过在环境变量中获取所需的字符串(可能仍然需要转义序列),然后使用延迟扩展和FOR/F将值传递给FOR变量,可以简化这一过程
- 在一些模糊的情况下,
可能会失败。唯一保证工作的安全变体是ECHO.
)ECHO(
- 如果替换字符串为空,则非空行在替换后可能变为空,并且空行将无法正确输出,因为未使用
或ECHO.
)ECHO(
- 重定向是为每一行输出执行的,速度较慢。最好(更快)在循环外重定向一次
- DEL/RENAME对可以由单个MOVE命令替换
- 呼叫速度相对较慢。如果您想要最快的解决方案,最好尽量减少呼叫的使用。但有时无法避免
- 我更喜欢将我的临时文件名作为原始名称的派生名称。我通常在原始名称后附加一个
扩展名,因此“original.txt”变成“original.txt.new”.new
@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字节
- 搜索忽略了案例
- 搜索字符串不能包含
或以=
、~
或*
开头!
- 替换字符串不能包含
!
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
。在嵌套中使用FOR
,即FOR/F“delims=“%%#in('dir/b/s”*mask.txt')do(FOR/F“tokens=1,*delims=”“%a in('“findstr/n^^%~#“')do(…)
注意,您的内部for/F
循环会从每一行中删除潜在的前导冒号:
;要避免这种情况,请使用“delims=”
,然后设置“string=%a”
,然后设置“string=!string::=!”!“
;这将删除行号和第一个:
前面的字符串,但没有其他内容…而不是echo!已修改!
您应该写入echo。!已修改!
以避免echo关闭pushd "c:\your\path\with\files\to\be\modified"
for %F in (*.txt) do call jrepl "Cat" "Dog" /l /f "%F" /o -
popd