【发布时间】:2011-07-13 12:51:27
【问题描述】:
谁能告诉我在 Windows 中使用批处理文件...如何从文件中读取并替换 string=bath from file contains=bath Abath Bbath XYZbathABC with string hello 这样输出就像hello Ahello Bhello XYZhelloABC
【问题讨论】:
标签: batch-file
谁能告诉我在 Windows 中使用批处理文件...如何从文件中读取并替换 string=bath from file contains=bath Abath Bbath XYZbathABC with string hello 这样输出就像hello Ahello Bhello XYZhelloABC
【问题讨论】:
标签: batch-file
从Andriy M 扩展,是的,您可以从一个文件中执行此操作,甚至是一个包含多行的文件
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=test.txt"
set "OUTTEXTFILE=test_out.txt"
set "SEARCHTEXT=bath"
set "REPLACETEXT=hello"
for /f "delims=" %%A in ('type "%INTEXTFILE%"') do (
set "string=%%A"
set "modified=!string:%SEARCHTEXT%=%REPLACETEXT%!"
echo !modified!>>"%OUTTEXTFILE%"
)
del "%INTEXTFILE%"
rename "%OUTTEXTFILE%" "%INTEXTFILE%"
endlocal
编辑
感谢 David Nelson,我已更新脚本,使其不再具有硬编码值。
【讨论】:
; 开头的行,因为它是选项 eol 的默认值.由于此代码需要启用延迟扩展,因此此代码无法正确处理具有一个或多个 ! 的行。 ECHO 在环境变量modified 被删除的情况下输出echo is off.,因为替换字符串是空字符串并且搜索字符串匹配整行。搜索字符串不能包含等号,因为= 在替换表达式中有特殊含义。
set "modified1=...,这段代码会有很大不同吗?
SET string=bath Abath Bbath XYZbathABC
SET modified=%string:bath=hello%
ECHO %string%
ECHO %modified%
编辑
起初并没有看到您希望在替换之前先从文件中读取字符串。
嗯,对于批处理文件,您没有太多处理文件的便利。在这种特殊情况下,您必须读取一行,执行替换,然后输出修改后的行,然后……然后呢?如果您需要替换所有文件中所有出现的“bath”,那么您将不得不使用循环:
@ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION
FOR /F %%L IN (file.txt) DO (
SET "line=%%L"
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO !line:bath=hello!
ENDLOCAL
)
ENDLOCAL
您可以向文件添加重定向:
ECHO !line:bath=hello!>>file2.txt
或者您可以将重定向应用到批处理文件。它必须是一个不同的文件。
编辑 2
添加了延迟扩展的适当切换,以正确处理具有批处理脚本语法的特殊含义的某些字符,例如!、^ 等。 (谢谢,jeb!)
【讨论】:
cscript 和PowerShell 在那里,我有时认为如果不是因为在整个Windows 领域可能仍在使用的大量脚本,他们会完全废弃批处理文件。
! 和^ 可以改进它的安全性,并打开和关闭延迟扩展,例如Improved BatchSubstitute
为了避免空行跳过(在 conf 文件中提供可读性),我将 aflat 和 jeb 答案 (here) 组合成如下内容:
@echo off
setlocal enabledelayedexpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
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%
【讨论】:
chcp 65001 用于 UTF8:请参阅 Echo UTF-8 characters in windows batch
为避免批处理解析器出现问题(例如感叹号),请查看Problem with search and replace batch file。
aflat的脚本修改后会包含感叹号等特殊字符。
@echo off
setlocal DisableDelayedExpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
set OUTPUTLINE=
for /f "tokens=1,* delims=¶" %%A in ( '"type %INTEXTFILE%"') do (
SET string=%%A
setlocal EnableDelayedExpansion
SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
>> %OUTTEXTFILE% echo(!modified!
endlocal
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%
【讨论】:
我为此做了一个函数,你只需要在批处理程序中调用它就可以了。
工作原理与其他基本相同,因为这是最好的方法。
Here's the link where I have that function
【讨论】:
为了避免空行跳过,只需替换这个:
echo !modified! >> %OUTTEXTFILE%
用这个:
echo.!modified! >> %OUTTEXTFILE%
【讨论】:
如果你有Ruby for Windows,
C:\>more file
bath Abath Bbath XYZbathABC
C:\>ruby -pne "$_.gsub!(/bath/,\"hello\")" file
hello Ahello Bhello XYZhelloABC
【讨论】: