如何在Windows命令行环境下查找并替换文件中的文本?

605

我正在使用Windows命令行环境编写批处理文件脚本,想要将文件中每个文本实例(例如 "FOO")更改为另一个文本(例如 "BAR")。最简单的方法是什么?是否有任何内置函数可以使用?

30个回答

17

当您使用Windows上的Git时,只需启动git-bash并使用sed。或者,在使用Windows 10时,启动Linux子系统中的“Bash on Ubuntu on Windows”并使用sed

sed是一种流编辑器,但可以通过以下命令直接编辑文件:

sed -i -e 's/foo/bar/g' filename
  • -i选项用于就地编辑文件。
  • -e选项指示要运行的命令。
    • s用于将找到的表达式“foo”替换为“bar”,g用于替换所有找到的匹配项。

说明:

如果您想仅在Git存储库的版本化文件中替换字符串,则可以使用:

git ls-files <可能的子文件夹和筛选器> | xargs sed -i -e 's/foo/bar/g'

这非常有效。


1
请注意,如果您确实在 git 存储库中进行重命名并且只想替换版本化文件,则可以执行以下操作:git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g',这将奏效。 - ereOn

15

我尝试了一些现有的答案,但更喜欢我的改进解决方案...

type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }"

或者,如果你想将输出再次保存到文件中...

type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }" > outputFile.txt

这样做的好处是你可以从任何程序中获取输出。还会研究如何使用正则表达式。但我无法弄成BAT文件以便更轻松地使用... :-(


3
这是一个不错的解决方案。不幸的是,使用“type”意味着所有大于80个字符的行都会被换行。太痛苦了。 - sirdank

15

我用过Perl,它非常出色。

perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" <fileName>

.orig是它会附加到原始文件的扩展名

对于多个匹配类似于*.html的文件

for %x in (<filePattern>) do perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" %x

这是最简单的解决方案+1,当从sh转换为bat时,只需用perl -pi.backup -e替换sed,并感谢它 :) - Yann39

13

使用replacer.bat

1) 使用e?选项,该选项将评估特殊字符序列,如\n\r和unicode序列。在这种情况下,将替换引用的"Foo""Bar"

call replacer.bat "e?C:\content.txt" "\u0022Foo\u0022" "\u0022Bar\u0022"

2)直接替换,不需要引用 FooBar

call replacer.bat "C:\content.txt" "Foo" "Bar"

你如何替换多个字符串?例如(不起作用)call replacer.bat "content.txt" "foo" "bar" "xyz abc" "bla fart"... - acgbox
@acgbox - 你可以多次调用它... - npocmaka

10

这里是我在Win XP上找到的解决方案。在我的批处理文件中,我包含了以下内容:

set value=new_value

:: Setup initial configuration
:: I use && as the delimiter in the file because it should not exist, thereby giving me the whole line
::
echo --> Setting configuration and properties.
for /f "tokens=* delims=&&" %%a in (config\config.txt) do ( 
  call replace.bat "%%a" _KEY_ %value% config\temp.txt 
)
del config\config.txt
rename config\temp.txt config.txt

replace.bat文件内容如下。我没有找到将该函数包含在同一批处理文件中的方法,因为%%a变量似乎总是给出for循环中的最后一个值。

@echo off

:: This ensures the parameters are resolved prior to the internal variable
::
SetLocal EnableDelayedExpansion

:: Replaces Key Variables
::
:: Parameters:
:: %1  = Line to search for replacement
:: %2  = Key to replace
:: %3  = Value to replace key with
:: %4  = File in which to write the replacement
::

:: Read in line without the surrounding double quotes (use ~)
::
set line=%~1

:: Write line to specified file, replacing key (%2) with value (%3)
::
echo !line:%2=%3! >> %4

:: Restore delayed expansion
::
EndLocal

1
遗憾的是,这也跳过了空行。这是{{for}}命令的一个“特性”。 - John Rocha

7
请看是否有类似于cmd.exe的sed实用程序,该问题要求在Windows下寻找sed等效工具,同样适用于此问题。执行摘要:
  • 可以在批处理文件中完成,但不太美观
  • 有很多可用的第三方可执行文件可为您完成此操作,如果您有安装或仅复制exe的奢侈条件
  • 如果需要在Windows框中运行某些内容而无需进行修改等,则可以使用VBScript或类似内容来完成此操作。

6
两个批处理文件,提供了“搜索和替换”功能,由Stack Overflow成员dbenham和aacini使用Windows的本地内置jscript编写。它们都非常强大,在处理大文件时非常快速,与纯批处理脚本相比也更简单易用于基本文本替换。它们都具有Windows正则表达式模式匹配功能。
  1. Thissed-like helper batch file is called repl.bat (by dbenham).

    Example using the L literal switch:

    echo This is FOO here|repl "FOO" "BAR" L
    echo and with a file:
    type "file.txt" |repl "FOO" "BAR" L >"newfile.txt"
    
  2. This grep-like helper batch file is called findrepl.bat (by aacini).

    Example which has regular expressions active:

    echo This is FOO here|findrepl "FOO" "BAR" 
    echo and with a file:
    type "file.txt" |findrepl "FOO" "BAR" >"newfile.txt"
    

当放置在路径上的文件夹中,或者与批处理文件或从cmd提示符中使用时,它们都成为功能强大的系统级实用程序。

它们都具有不区分大小写的开关和许多其他功能。


5

我更喜欢使用GNU Windows实用程序中的sed,需要注意以下几点:

  • 在Windows中,单引号''无法正常工作,请改用双引号""
  • sed -i在Windows中无法正常工作,需要进行文件交换

因此,在Windows中查找和替换文件中文本的有效sed代码如下:

sed -e "s/foo/bar/g" test.txt > tmp.txt && mv tmp.txt test.txt

4
在Windows用户进行文件交换之前,请注意:较新版本的sed支持使用“-i”进行原地编辑!如果您的sed版本支持,则可以查看此答案中的命令:https://dev59.com/tXVD5IYBdhLWcg3wL4cA#33762001。 - Benjamin Bihler

5

可能有点晚了,但我经常寻找类似的东西,因为我不想经历软件审核的痛苦。

然而,通常你会使用各种形式的FOR语句。有人创建了一个有用的批处理文件来进行搜索和替换。请看这里。重要的是要了解提供的批处理文件的限制。因此,我不在此答案中复制源代码。


5

Power shell命令非常好用

(
test.txt | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test2.txt
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接