ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 Windows 命令行环境查找和替换文件中的文本?

我正在使用 Windows 命令行环境编写批处理文件脚本,并希望将文件中某些文本(例如“FOO”)的每次出现都更改为另一个(例如“BAR”)。最简单的方法是什么?有内置函数吗?


R
Rachel

这里的很多答案帮助我指出了正确的方向,但是没有一个适合我,所以我发布了我的解决方案。

我有内置 PowerShell 的 Windows 7。这是我用来查找/替换文件中所有文本实例的脚本:

powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt"

解释一下:

powershell 启动 powershell.exe,它包含在 Windows 7 中

-Command "..." 是 powershell.exe 的命令行参数,包含要运行的命令

(gc myFile.txt) 读取 myFile.txt 的内容(gc 是 Get-Content 命令的缩写)

-replace 'foo', 'bar' 只需运行替换命令以将 foo 替换为 bar

| Out-File myFile.txt 将输出通过管道传输到文件 myFile.txt

-encoding ASCII 防止将输出文件转录为 unicode,正如注释所指出的那样

Powershell.exe 应该已经是您的 PATH 语句的一部分,但如果不是,您可以添加它。它在我的机器上的位置是 C:\WINDOWS\system32\WindowsPowerShell\v1.0

更新 显然,现代 Windows 系统内置了 PowerShell,允许您直接使用

(Get-Content myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt

请注意,此命令也可能将文件转码为 Unicode 编码。您可以通过添加 -encoding ASCIIUTF8 或任何需要的内容来手动指定编码。另请注意,如果您以 UTF8 为目标,它可能会在文件开头引入一个原始文件中未出现的字节顺序标记。
@Wyck 我花了一段时间才弄清楚将 -encoding ASCII 放在哪里。对于将来需要它的任何人,它将是 Out-File -encoding ASCII myFile.txt
我唯一需要改变的是使用 Set-Content 而不是 Out-File
这可行,但即使是简短的文件列表,性能也很糟糕。
请注意,替换标记(在本例中为“foo”)被视为正则表达式。如果那里有任何特殊字符(我有 [ ] ),则需要在它们前面加上 \ (反斜杠)。
M
Michael Haren

如果您使用的是支持 .Net 2.0 的 Windows 版本,我会替换您的 shell。 PowerShell 从命令行为您提供 .Net 的全部功能。还有许多内置的命令行开关。下面的示例将解决您的问题。我使用的是命令的全名,还有更短的别名,但这给了谷歌一些东西。

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

我可以看到 PowerShell 能够对此进行归档。但是我怎样才能从批处理文件(例如:myProc.bat)中运行呢?
@Pablo,使用 powershell.exe 并将 ps 命令包装成单个参数
-1 .. 确定答案已被接受,但不是指定问题的答案。
如果保存到同一个文件,这将失败并出现文件正在使用错误。您需要将 powershell 命令更改为: (Get-Content test.txt) | ForEach-Object { $_ -replace "foo", "bar" } |设置内容 test.txt
查看@Rachel 的答案:powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | sc myFile.txt"
V
VonC

刚刚使用 FART ("F ind A nd R eplace T ext " 命令行实用程序):
用于在大量文件中替换文本的优秀小免费软件。

设置文件 are on SourceForge

使用示例:

fart.exe -p -r -c -- C:\tools\perl-5.8.9\* @@APP_DIR@@ C:\tools

将在此 Perl 发行版的文件中预览要递归执行的替换。

唯一的问题:FART 网站图标并不完全有品味、精致或优雅;)

2017 年更新(7 年后)jagb 指出 in the comments 来自 Mikail Tunç 的 2011 年文章“FARTing the Easy Way – Find And Replace Text

正如 the comments(2020 年 12 月)中的 Joe Jobs 所述,例如,如果您想替换 &A,则需要使用引号以确保 shell 不会解释 &

fart in.txt "&A" "B" 

很酷的是它是一个单独的 exe。没有依赖关系。没有小印记。超级容易部署。
谢谢你的屁推荐。似乎运作良好,虽然我希望它支持正则表达式。
非常轻巧且易于使用,但我希望它能打印出更换的确切位置。看不到这一点让我有一种不安全感。
谢谢,它很完美,应该是标准dos工具的一部分,并且很有魅力。但是,-p 选项不会向您显示它“将”进行多少更改,并且总是报告 0 这让我花了几分钟
我知道这是一个非常古老的问题,但我找到了更多信息,并希望它对 Stack Overflow 用户有所帮助。只是 FART 的另一个链接,其中对产品进行了很好的解释:FART explaned @emtunc.org 可以在此处找到另一个页面:FART 请小心替换 /',因为这不适用于所有我们,对我来说,它在某些情况下有效,但它不适用于某些文件,我不知道为什么..我用它用其他文本和 / 替换文本
R
RB.

替换 - 使用字符串替换替换子字符串 描述:要用另一个字符串替换子字符串,请使用字符串替换功能。此处显示的示例将字符串变量 str 中所有出现的“teh”拼写错误替换为“the”。

set str=teh cat in teh hat
echo.%str%
set str=%str:teh=the%
echo.%str%

脚本输出:

teh cat in teh hat
the cat in the hat

参考:http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace


sed 建议如何更好?这似乎是所有这些中最简单的答案,并且不需要安装任何东西。
可以在这里进行任何类型的模式匹配吗?通配符,正则表达式等?
“sed 建议如何更好?” - sed 和类似的实用程序对文件进行操作;此片段省略了从输入文件读取行并写入输出文件的重要步骤,同时确保正确处理文件中的任何特殊字符。
@Asad,是的,这是真的,OP 在询问文件,但实际上它适用于不一定是文件的流。但我的观点是,这个答案是有缺陷的,因为它省略了从流中读取/写入并处理任何特殊字符。
@Bill 如何使用变量作为替换文本? IE。我在一个变量和一个带有一些分隔符的字符串中有值。设置 str=%str:"##"=%varValue%% 不起作用。任何解决方法?
J
JamesQMurphy

创建文件replace.vbs:

Const ForReading = 1    
Const ForWriting = 2

strFileName = Wscript.Arguments(0)
strOldText = Wscript.Arguments(1)
strNewText = Wscript.Arguments(2)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFileName, ForReading)
strText = objFile.ReadAll
objFile.Close

strNewText = Replace(strText, strOldText, strNewText)
Set objFile = objFSO.OpenTextFile(strFileName, ForWriting)
objFile.Write strNewText  'WriteLine adds extra CR/LF
objFile.Close

要使用这个修改后的脚本(我们将其称为 replace.vbs),只需在命令提示符下键入与此类似的命令:

cscript replace.vbs "C:\Scripts\Text.txt" "Jim " "James "


这很整洁,它允许使用 RegEx 吗?
@user280109 是的,VBScript 支持 RegExp。您可以使用它来使用正则表达式进行替换:With (New RegExp): strNewText = .Replace(strText, strOldText, strNewText): End With。您可以使用 $1$2 ... $9 获取前 9 个捕获组的文本。
VBScript 经常被忽视(和讨厌),但在所有 Windows 平台上都可用,非常易读并且实际上具有非常强大的功能 +1
@user280109 你刚刚给出了我需要的命令。但我想替换(不区分大小写)你能提供命令吗?
谢谢,这个脚本很棒,我喜欢你的前缀(str 和 obj 字),我也这样做,它很旧但很黄金,它使代码更具可读性。
C
Community

BatchSubstitute.bat on dostips.com 是使用纯批处理文件进行搜索和替换的示例。

它使用 FORFINDCALL SET 的组合。

"&<>]|^ 中包含字符的行可能会被错误地处理。


我不得不质疑 terms of use 禁止复制任何代码的代码片段网站的有用性(“未经域所有者的明确书面许可,您不得以任何形式分发在域 dostips.com 下提供的任何信息。”) .
我同意他们的条款令人困惑,他们还说“在 dostips.com 域下提供的信息希望很有用”,所以我的假设是他们乐于让人们复制代码来解决问题。我不确定我是否曾经阅读过任何条款和条件并感到高兴...
这很棒。我喜欢不涉及下载其他内容的答案。
我也喜欢不涉及外部实用程序的解决方案,不幸的是,当我尝试运行此批处理时,我不断收到“find:invalid predicate `'”。现在真的没有时间调试它。
“find:invalid predicate `'”错误是由于我系统上的外部“find”实用程序造成的。一旦删除,这工作正常。
d
dbenham

注意 - 请务必查看此答案末尾的更新,以获取替代 REPL.BAT 的高级 JREPL.BAT 的链接< br> JREPL.BAT 7.0 and above 通过 /UTF 选项本机支持 unicode (UTF-16LE),以及通过 ADO 支持任何其他字符集,包括 UTF-8!!!!

I have written a small hybrid JScript/batch utility called REPL.BAT 非常方便通过命令行或批处理文件修改 ASCII(或扩展的 ASCII)文件。纯本机脚本不需要安装任何第 3 方可执行文件,它适用于 XP 以后的任何现代 Windows 版本。它也非常快,特别是与纯批处理解决方案相比。

REPL.BAT 只是读取标准输入,执行 JScript 正则表达式搜索和替换,然后将结果写入标准输出。

这是一个关于如何在 test.txt 中用 bar 替换 foo 的简单示例,假设 REPL.BAT 在您当前的文件夹中,或者更好的是,在您的 PATH 中的某个位置:

type test.txt|repl "foo" "bar" >test.txt.new
move /y test.txt.new test.txt

JScript 正则表达式功能使其非常强大,尤其是替换文本从搜索文本中引用捕获的子字符串的能力。

我在实用程序中包含了许多选项,使其非常强大。例如,结合 MX 选项可以修改二进制文件! M 多行选项允许跨多行搜索。 X 扩展替换模式选项提供了能够在替换文本中包含任何二进制值的转义序列。

整个实用程序可以编写为纯 JScript,但混合批处理文件消除了每次要使用该实用程序时显式指定 CSCRIPT 的需要。

这是 REPL.BAT 脚本。完整的文档嵌入在脚本中。

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment

::************ Documentation ***********
::REPL.BAT version 6.2
:::
:::REPL  Search  Replace  [Options  [SourceVar]]
:::REPL  /?[REGEX|REPLACE]
:::REPL  /V
:::
:::  Performs a global regular expression search and replace operation on
:::  each line of input from stdin and prints the result to stdout.
:::
:::  Each parameter may be optionally enclosed by double quotes. The double
:::  quotes are not considered part of the argument. The quotes are required
:::  if the parameter contains a batch token delimiter like space, tab, comma,
:::  semicolon. The quotes should also be used if the argument contains a
:::  batch special character like &, |, etc. so that the special character
:::  does not need to be escaped with ^.
:::
:::  If called with a single argument of /?, then prints help documentation
:::  to stdout. If a single argument of /?REGEX, then opens up Microsoft's
:::  JScript regular expression documentation within your browser. If a single
:::  argument of /?REPLACE, then opens up Microsoft's JScript REPLACE
:::  documentation within your browser.
:::
:::  If called with a single argument of /V, case insensitive, then prints
:::  the version of REPL.BAT.
:::
:::  Search  - By default, this is a case sensitive JScript (ECMA) regular
:::            expression expressed as a string.
:::
:::            JScript regex syntax documentation is available at
:::            http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx
:::
:::  Replace - By default, this is the string to be used as a replacement for
:::            each found search expression. Full support is provided for
:::            substituion patterns available to the JScript replace method.
:::
:::            For example, $& represents the portion of the source that matched
:::            the entire search pattern, $1 represents the first captured
:::            submatch, $2 the second captured submatch, etc. A $ literal
:::            can be escaped as $$.
:::
:::            An empty replacement string must be represented as "".
:::
:::            Replace substitution pattern syntax is fully documented at
:::            http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx
:::
:::  Options - An optional string of characters used to alter the behavior
:::            of REPL. The option characters are case insensitive, and may
:::            appear in any order.
:::
:::            A - Only print altered lines. Unaltered lines are discarded.
:::                If the S options is present, then prints the result only if
:::                there was a change anywhere in the string. The A option is
:::                incompatible with the M option unless the S option is present.
:::
:::            B - The Search must match the beginning of a line.
:::                Mostly used with literal searches.
:::
:::            E - The Search must match the end of a line.
:::                Mostly used with literal searches.
:::
:::            I - Makes the search case-insensitive.
:::
:::            J - The Replace argument represents a JScript expression.
:::                The expression may access an array like arguments object
:::                named $. However, $ is not a true array object.
:::
:::                The $.length property contains the total number of arguments
:::                available. The $.length value is equal to n+3, where n is the
:::                number of capturing left parentheses within the Search string.
:::
:::                $[0] is the substring that matched the Search,
:::                $[1] through $[n] are the captured submatch strings,
:::                $[n+1] is the offset where the match occurred, and
:::                $[n+2] is the original source string.
:::
:::                Arguments $[0] through $[10] may be abbreviated as
:::                $1 through $10. Argument $[11] and above must use the square
:::                bracket notation.
:::
:::            L - The Search is treated as a string literal instead of a
:::                regular expression. Also, all $ found in the Replace string
:::                are treated as $ literals.
:::
:::            M - Multi-line mode. The entire contents of stdin is read and
:::                processed in one pass instead of line by line, thus enabling
:::                search for \n. This also enables preservation of the original
:::                line terminators. If the M option is not present, then every
:::                printed line is terminated with carriage return and line feed.
:::                The M option is incompatible with the A option unless the S
:::                option is also present.
:::
:::                Note: If working with binary data containing NULL bytes,
:::                      then the M option must be used.
:::
:::            S - The source is read from an environment variable instead of
:::                from stdin. The name of the source environment variable is
:::                specified in the next argument after the option string. Without
:::                the M option, ^ anchors the beginning of the string, and $ the
:::                end of the string. With the M option, ^ anchors the beginning
:::                of a line, and $ the end of a line.
:::
:::            V - Search and Replace represent the name of environment
:::                variables that contain the respective values. An undefined
:::                variable is treated as an empty string.
:::
:::            X - Enables extended substitution pattern syntax with support
:::                for the following escape sequences within the Replace string:
:::
:::                \\     -  Backslash
:::                \b     -  Backspace
:::                \f     -  Formfeed
:::                \n     -  Newline
:::                \q     -  Quote
:::                \r     -  Carriage Return
:::                \t     -  Horizontal Tab
:::                \v     -  Vertical Tab
:::                \xnn   -  Extended ASCII byte code expressed as 2 hex digits
:::                \unnnn -  Unicode character expressed as 4 hex digits
:::
:::                Also enables the \q escape sequence for the Search string.
:::                The other escape sequences are already standard for a regular
:::                expression Search string.
:::
:::                Also modifies the behavior of \xnn in the Search string to work
:::                properly with extended ASCII byte codes.
:::
:::                Extended escape sequences are supported even when the L option
:::                is used. Both Search and Replace support all of the extended
:::                escape sequences if both the X and L opions are combined.
:::
:::  Return Codes:  0 = At least one change was made
:::                     or the /? or /V option was used
:::
:::                 1 = No change was made
:::
:::                 2 = Invalid call syntax or incompatible options
:::
:::                 3 = JScript runtime error, typically due to invalid regex
:::
::: REPL.BAT was written by Dave Benham, with assistance from DosTips user Aacini
::: to get \xnn to work properly with extended ASCII byte codes. Also assistance
::: from DosTips user penpen diagnosing issues reading NULL bytes, along with a
::: workaround. REPL.BAT was originally posted at:
::: http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
:::

::************ Batch portion ***********
@echo off
if .%2 equ . (
  if "%~1" equ "/?" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^:::" "" a
    exit /b 0
  ) else if /i "%~1" equ "/?regex" (
    explorer "http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/?replace" (
    explorer "http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/V" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^::(REPL\.BAT version)" "$1" a
    exit /b 0
  ) else (
    call :err "Insufficient arguments"
    exit /b 2
  )
)
echo(%~3|findstr /i "[^SMILEBVXAJ]" >nul && (
  call :err "Invalid option(s)"
  exit /b 2
)
echo(%~3|findstr /i "M"|findstr /i "A"|findstr /vi "S" >nul && (
  call :err "Incompatible options"
  exit /b 2
)
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%

:err
>&2 echo ERROR: %~1. Use REPL /? to get help.
exit /b

************* JScript portion **********/
var rtn=1;
try {
  var env=WScript.CreateObject("WScript.Shell").Environment("Process");
  var args=WScript.Arguments;
  var search=args.Item(0);
  var replace=args.Item(1);
  var options="g";
  if (args.length>2) options+=args.Item(2).toLowerCase();
  var multi=(options.indexOf("m")>=0);
  var alterations=(options.indexOf("a")>=0);
  if (alterations) options=options.replace(/a/g,"");
  var srcVar=(options.indexOf("s")>=0);
  if (srcVar) options=options.replace(/s/g,"");
  var jexpr=(options.indexOf("j")>=0);
  if (jexpr) options=options.replace(/j/g,"");
  if (options.indexOf("v")>=0) {
    options=options.replace(/v/g,"");
    search=env(search);
    replace=env(replace);
  }
  if (options.indexOf("x")>=0) {
    options=options.replace(/x/g,"");
    if (!jexpr) {
      replace=replace.replace(/\\\\/g,"\\B");
      replace=replace.replace(/\\q/g,"\"");
      replace=replace.replace(/\\x80/g,"\\u20AC");
      replace=replace.replace(/\\x82/g,"\\u201A");
      replace=replace.replace(/\\x83/g,"\\u0192");
      replace=replace.replace(/\\x84/g,"\\u201E");
      replace=replace.replace(/\\x85/g,"\\u2026");
      replace=replace.replace(/\\x86/g,"\\u2020");
      replace=replace.replace(/\\x87/g,"\\u2021");
      replace=replace.replace(/\\x88/g,"\\u02C6");
      replace=replace.replace(/\\x89/g,"\\u2030");
      replace=replace.replace(/\\x8[aA]/g,"\\u0160");
      replace=replace.replace(/\\x8[bB]/g,"\\u2039");
      replace=replace.replace(/\\x8[cC]/g,"\\u0152");
      replace=replace.replace(/\\x8[eE]/g,"\\u017D");
      replace=replace.replace(/\\x91/g,"\\u2018");
      replace=replace.replace(/\\x92/g,"\\u2019");
      replace=replace.replace(/\\x93/g,"\\u201C");
      replace=replace.replace(/\\x94/g,"\\u201D");
      replace=replace.replace(/\\x95/g,"\\u2022");
      replace=replace.replace(/\\x96/g,"\\u2013");
      replace=replace.replace(/\\x97/g,"\\u2014");
      replace=replace.replace(/\\x98/g,"\\u02DC");
      replace=replace.replace(/\\x99/g,"\\u2122");
      replace=replace.replace(/\\x9[aA]/g,"\\u0161");
      replace=replace.replace(/\\x9[bB]/g,"\\u203A");
      replace=replace.replace(/\\x9[cC]/g,"\\u0153");
      replace=replace.replace(/\\x9[dD]/g,"\\u009D");
      replace=replace.replace(/\\x9[eE]/g,"\\u017E");
      replace=replace.replace(/\\x9[fF]/g,"\\u0178");
      replace=replace.replace(/\\b/g,"\b");
      replace=replace.replace(/\\f/g,"\f");
      replace=replace.replace(/\\n/g,"\n");
      replace=replace.replace(/\\r/g,"\r");
      replace=replace.replace(/\\t/g,"\t");
      replace=replace.replace(/\\v/g,"\v");
      replace=replace.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      replace=replace.replace(/\\B/g,"\\");
    }
    search=search.replace(/\\\\/g,"\\B");
    search=search.replace(/\\q/g,"\"");
    search=search.replace(/\\x80/g,"\\u20AC");
    search=search.replace(/\\x82/g,"\\u201A");
    search=search.replace(/\\x83/g,"\\u0192");
    search=search.replace(/\\x84/g,"\\u201E");
    search=search.replace(/\\x85/g,"\\u2026");
    search=search.replace(/\\x86/g,"\\u2020");
    search=search.replace(/\\x87/g,"\\u2021");
    search=search.replace(/\\x88/g,"\\u02C6");
    search=search.replace(/\\x89/g,"\\u2030");
    search=search.replace(/\\x8[aA]/g,"\\u0160");
    search=search.replace(/\\x8[bB]/g,"\\u2039");
    search=search.replace(/\\x8[cC]/g,"\\u0152");
    search=search.replace(/\\x8[eE]/g,"\\u017D");
    search=search.replace(/\\x91/g,"\\u2018");
    search=search.replace(/\\x92/g,"\\u2019");
    search=search.replace(/\\x93/g,"\\u201C");
    search=search.replace(/\\x94/g,"\\u201D");
    search=search.replace(/\\x95/g,"\\u2022");
    search=search.replace(/\\x96/g,"\\u2013");
    search=search.replace(/\\x97/g,"\\u2014");
    search=search.replace(/\\x98/g,"\\u02DC");
    search=search.replace(/\\x99/g,"\\u2122");
    search=search.replace(/\\x9[aA]/g,"\\u0161");
    search=search.replace(/\\x9[bB]/g,"\\u203A");
    search=search.replace(/\\x9[cC]/g,"\\u0153");
    search=search.replace(/\\x9[dD]/g,"\\u009D");
    search=search.replace(/\\x9[eE]/g,"\\u017E");
    search=search.replace(/\\x9[fF]/g,"\\u0178");
    if (options.indexOf("l")>=0) {
      search=search.replace(/\\b/g,"\b");
      search=search.replace(/\\f/g,"\f");
      search=search.replace(/\\n/g,"\n");
      search=search.replace(/\\r/g,"\r");
      search=search.replace(/\\t/g,"\t");
      search=search.replace(/\\v/g,"\v");
      search=search.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      search=search.replace(/\\B/g,"\\");
    } else search=search.replace(/\\B/g,"\\\\");
  }
  if (options.indexOf("l")>=0) {
    options=options.replace(/l/g,"");
    search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1");
    if (!jexpr) replace=replace.replace(/\$/g,"$$$$");
  }
  if (options.indexOf("b")>=0) {
    options=options.replace(/b/g,"");
    search="^"+search
  }
  if (options.indexOf("e")>=0) {
    options=options.replace(/e/g,"");
    search=search+"$"
  }
  var search=new RegExp(search,options);
  var str1, str2;

  if (srcVar) {
    str1=env(args.Item(3));
    str2=str1.replace(search,jexpr?replFunc:replace);
    if (!alterations || str1!=str2) if (multi) {
      WScript.Stdout.Write(str2);
    } else {
      WScript.Stdout.WriteLine(str2);
    }
    if (str1!=str2) rtn=0;
  } else if (multi){
    var buf=1024;
    str1="";
    while (!WScript.StdIn.AtEndOfStream) {
      str1+=WScript.StdIn.Read(buf);
      buf*=2
    }
    str2=str1.replace(search,jexpr?replFunc:replace);
    WScript.Stdout.Write(str2);
    if (str1!=str2) rtn=0;
  } else {
    while (!WScript.StdIn.AtEndOfStream) {
      str1=WScript.StdIn.ReadLine();
      str2=str1.replace(search,jexpr?replFunc:replace);
      if (!alterations || str1!=str2) WScript.Stdout.WriteLine(str2);
      if (str1!=str2) rtn=0;
    }
  }
} catch(e) {
  WScript.Stderr.WriteLine("JScript runtime error: "+e.message);
  rtn=3;
}
WScript.Quit(rtn);

function replFunc($0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10) {
  var $=arguments;
  return(eval(replace));
}

重要更新

我已经停止了 REPL.BAT 的开发,并用 JREPL.BAT 代替了它。这个较新的实用程序具有 REPL.BAT 的所有相同功能,以及更多功能:

通过本机 CSCRIPT unicode 功能支持 Unicode UTF-16LE,通过 ADO 支持任何其他字符集(包括 UTF-8)。

直接从文件读取/直接写入文件:不需要管道、重定向或移动命令。

合并用户提供的 JScript

类似于 unix tr 的翻译工具,只是它还支持正则表达式搜索和 JScript 替换

丢弃不匹配的文本

使用行号为输出行添加前缀

和更多...

与往常一样,完整的文档嵌入在脚本中。

原来的简单解决方案现在更加简单:

jrepl "foo" "bar" /f test.txt /o -

The current version of JREPL.BAT is available at DosTips。阅读线程中的所有后续帖子,以查看使用示例和开发历史。


好东西!我喜欢这种简单的 b/c 以及您可以将其适应任何脚本的方式,因此编写 JS 代码而不是糟糕的批处理。
编辑 - 添加了 A 选项以仅打印已修改的行。还增强了 X 选项以支持 \q 来表示 ",并且当 L 和 X 选项组合时,搜索文字现在支持所有扩展的转义序列。
@dbenham - +1。这是一种巧妙的方法,它也可以用于其他几项任务。感谢您发布它。
编辑 - 当使用 X 选项时,我修改了 \xnn 的行为,以便代码表示扩展的 ASCII 字节码。还添加了 /V 版本选项。
@dbenham 这是一颗宝石。你为什么不把它放在 GitHub 上或者作为 Gist 呢?将使版本控制、跟进、发布/分发、修复和更容易。如果您需要这方面的帮助,请告诉我。
C
Community

使用 FNR

使用 fnr 实用程序。它比 fart 有一些优势:

常用表达

可选的图形用户界面。有一个“生成命令行按钮”来创建命令行文本以放入批处理文件。

多线模式:GUI 允许您轻松使用多线模式。在 FART 中,您必须手动转义换行符。

允许您选择文本文件编码。还有一个自动检测选项。

在此处下载 FNR:http://findandreplace.io/?z=codeplex

使用示例:fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"


这很好。能够从 gui 生成命令行是一个很好的简单功能,让我快速上手。
非常有用的工具。之前尝试过 FART,但文档已过时。
很酷的工具,它甚至支持正则表达式。这是 FART 所缺少的。
感谢您提供此工具。单个 exe,可以很好地替代不再开发的 FART(并且缺少正则表达式);并且 PowerShell 语法太难以忍受了。
“放屁”的最大优势是释放胃
L
Leptonator

我知道我迟到了。。

就个人而言,我喜欢以下解决方案:- http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace

我们还广泛使用重复数据删除功能来帮助我们每天通过 SMTP 从以下地址发送大约 500 封电子邮件:- https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o

这些都可以在本地工作,不需要额外的工具或实用程序。

替代品:

DEL New.txt
setLocal EnableDelayedExpansion
For /f "tokens=* delims= " %%a in (OLD.txt) do (
Set str=%%a
set str=!str:FOO=BAR!
echo !str!>>New.txt
)
ENDLOCAL

DEDUPLICATOR(注意使用 -9 表示 ABA 编号):

REM DE-DUPLICATE THE Mapping.txt FILE
REM THE DE-DUPLICATED FILE IS STORED AS new.txt

set MapFile=Mapping.txt
set ReplaceFile=New.txt

del %ReplaceFile%
::DelDupeText.bat
rem https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o
setLocal EnableDelayedExpansion
for /f "tokens=1,2 delims=," %%a in (%MapFile%) do (
set str=%%a
rem Ref: http://www.dostips.com/DtTipsStringManipulation.php#Snippets.RightString
set str=!str:~-9!
set str2=%%a
set str3=%%a,%%b

find /i ^"!str!^" %MapFile%
find /i ^"!str!^" %ReplaceFile%
if errorlevel 1 echo !str3!>>%ReplaceFile%
)
ENDLOCAL

谢谢!


批处理脚本只做一个文件复制 - 还有:你为什么要感谢自己?
最初的要求是使用批处理脚本并最好使用内置函数将文本文件中的“FOO”替换为“BAR”。如果有什么我要感谢 Google Groups 的帖子,我发现它非常有效,我们至今仍在使用它。此外,请查看此类帖子和回复,这些帖子和回复也对未来的用户有所帮助。我看不到您对文件复制的评论。当然,它会将一个文件的内容并将结果回显到另一个文件中,但是根据数据,它确实会修剪和解析所需的信息。我建议先试一试。 ;)
它基本上是一个文件复制工具,它替换了两个静态字符串 - 你至少可以在其中放置两个变量,所以想要尝试它的人不需要理解语法以便实际能够使用它 - 还有:互联网上的假设几乎总是完全错误的。记住这一点。
@specializt - 请......我不是来讨论语义的。如果您愿意,我们可以将其离线进入聊天室吗?
在我看来,这是原始问题的答案。我将使用此技巧在设置期间为服务配置初始化文件,并且我不想启用 PowerShell,或允许脚本引擎在我的服务器上运行。所以经常回答与 Windows 相关的问题,从“从那里安装这个小玩意”开始,因为周围仍然存在“PC”的态度。
P
Pat

我认为没有办法使用任何内置命令来做到这一点。我建议您下载 Gnuwin32UnxUtils 之类的内容并使用 sed 命令(或仅下载 sed):

sed -c s/FOO/BAR/g filename

使用 cygwin (cygwin.com)。这是实际安装 linux 的下一个最佳选择。
最好能提供一个不依赖安装cygwin的解决方案。 POSIX 字符串操作是轻而易举的事——在 Windows 上执行此操作有点晦涩难懂。
Gnuwin32 和 UnxUtils 是为 Windows 构建的独立二进制文件。它们不依赖于cygwin。
cygwin: sed -i -b -e 's/FOO/BAR/g' `find . -name *.txt` -i -- 就地编辑文件; -b -- 不处理 CR+LF - 没有这个选项 CR+LF 将被转换为 LF
@AndrewJohnson 意见和信息是两件不同的事情。
J
Jens A. Koch

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

它是一个流编辑器,但可以使用以下命令直接编辑文件:

sed -i -e 's/foo/bar/g' filename

-i 选项用于在文件名上进行就地编辑。

-e 选项表示要运行的命令。 s 用于将找到的表达式“foo”替换为“bar”,g 用于替换任何找到的匹配项。

s 用于将找到的表达式“foo”替换为“bar”,g 用于替换任何找到的匹配项。

ereOn 的注释:

如果您只想替换 Git 存储库的版本控制文件中的字符串,您可能需要使用:

git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'

这很有效。


请注意,如果您确实在 git 存储库中进行了重命名,并且只想在版本化文件中进行替换,那么您可能想要这样做:git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g' 这很有效。
S
Simon East

我在这里玩了一些现有的答案,并更喜欢我改进的解决方案......

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 文件以便于使用... :-(


这是一个很好的解决方案。不幸的是,使用 type 意味着所有超过 80 个字符的行都会被换行。多么痛苦。
C
CoolBeans

我用过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 时,只需将 sed 替换为 perl -pi.backup -e 即可:)
G
Gilles 'SO- stop being evil'

这是我发现适用于 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 循环中的最后一个值。

replace.bat

@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

可悲的是,这也跳过了空白行。 {{for}} 命令的一项功能。
n
npocmaka

使用 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"

C
Community

看看在 Windows 下要求 sed 等效项的 Is there any sed like utility for cmd.exe,也应该适用于这个问题。执行摘要:

它可以在批处理文件中完成,但它并不漂亮

如果您有安装或只是复制 exe 的奢侈,许多可用的第三方可执行文件将为您完成

如果您需要能够在 Windows 机器上运行而无需修改等的东西,可以使用 VBScript 或类似工具来完成。


C
Cody Gray

Power shell 命令就像一个魅力

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

U
Usman Maqbool

Stack Overflow 成员 dbenhamaacini 在 Windows 中使用 native built-in jscript 编写了两个提供 search and replace 函数的批处理文件。

与普通批处理脚本相比,它们既是 robust 又是 very swift with large files,也是用于基本替换文本的 simpler。它们都有 Windows regular expression 模式匹配。

Thissed 类似的帮助批处理文件称为 repl.bat(由 dbenham 提供)。使用 L 文字开关的示例: echo This is FOO here|repl "FOO" "BAR" L echo 并带有文件: type "file.txt" |repl "FOO" "BAR" L >"newfile.txt" This grep -like helper 批处理文件称为 findrepl.bat(由 aacini 提供)。激活正则表达式的示例: echo This is FOO here|findrepl "FOO" "BAR" echo 并带有文件: type "file.txt" |findrepl "FOO" "BAR" >"newfile.txt"

两者都成为强大的系统范围实用程序 when placed in a folder that is on the path,或者可以与批处理文件在同一文件夹中使用,或者在 cmd 提示符下使用。

它们都有 case-insensitive 开关和许多其他功能。


P
Peter Schuetze

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

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


e
eQ19

我更喜欢使用GNU utilities for Win32中的sed,需要注意以下几点

单引号 '' 在 Windows 中不起作用,使用 "" 代替 sed -i 在 Windows 中不起作用,它需要文件交换

所以 sed 在 windows 中查找和替换文件中的文本的工作代码如下

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

在 Windows 用户立即进行文件交换之前:较新版本的 sed 支持使用 -i 进行就地编辑!如果您的 sed 版本有,请检查此答案中的命令:stackoverflow.com/a/33762001/2492801
j
jeb

刚刚遇到一个类似的问题 - “在文件中搜索和替换文本”,但除了文件名和搜索/替换我需要使用正则表达式。因为我不熟悉 Powershell 并且想保存我的搜索以供以后使用,所以我需要一些更“用户友好”的东西(如果它有 GUI,则更可取)。

因此,在谷歌搜索时 :) 我发现了一个很棒的工具 - FAR (Find And Replace)(不是 FART)。

这个小程序有很好的 GUI 并支持正则表达式来搜索文件名和文件。唯一的缺点是如果你想保存你的设置,你必须以管理员身份运行程序(至少在 Win7 上)。


W
Wagner Pereira

在 .bat 中使用 powershell - 适用于 Windows 7+

编码 utf8 是可选的,适用于网站

@echo off
set ffile='myfile.txt'
set fold='FOO'
set fnew='BAR'
powershell -Command "(gc %ffile%) -replace %fold%, %fnew% | Out-File %ffile% -encoding utf8"

佚名

这是批处理脚本做得不好的一件事。

链接到的脚本 morechilli 将适用于某些文件,但不幸的是,它会阻塞包含诸如管道和 & 符号等字符的文件。

VBScript 是完成此任务的更好的内置工具。有关示例,请参见这篇文章:http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0208.mspx


W
Whome

@Rachel 给出了一个很好的答案,但这里是它的一个变体,用于将内容读取到 powershell $data 变量。然后,您可以在写入输出文件之前轻松多次操作内容。另请参阅 .bat 批处理文件中如何给出多行值。

@REM ASCII=7bit ascii(no bom), UTF8=with bom marker
set cmd=^
  $old = '\$Param1\$'; ^
  $new = 'Value1'; ^
  [string[]]$data = Get-Content 'datafile.txt'; ^
  $data = $data -replace $old, $new; ^
  out-file -InputObject $data -encoding UTF8 -filepath 'datafile.txt';
powershell -NoLogo -Noninteractive -InputFormat none -Command "%cmd%"

G
Georgie

对我来说,要确保不更改编码(来自 UTF-8),保持重音符号......唯一的方法是在之前和之后提及默认编码:

powershell -Command "(gc 'My file.sql' -encoding "Default") -replace 'String 1', 'String 2' | Out-File -encoding "Default" 'My file.sql'"

j
jm.

下载 Cygwin(免费)并在 Windows 命令行中使用类似 unix 的命令。

你最好的选择:sed


Cygwin是邪恶的。不要安装它。最好使用下面提到的 UnixUtils。
@jm 可能是因为您必须一起安装整个东西,而不是随时使用单个可执行文件。
最好使用powershell,它实际上是内置在windows中的。
Cygwin 有已知问题。不使用。
G
George Birbilis

还可以在 https://zoomicon.github.io/tranXform/ 中查看 Replace 和 ReplaceFilter 工具(包括源代码)。第二个是过滤器。

替换文件中字符串的工具在 VBScript 中(需要 Windows Script Host [WSH] 才能在旧 Windows 版本中运行)

除非您使用最新的 Delphi(或使用 FreePascal/Lazarus)重新编译,否则过滤器可能不适用于 Unicode


S
Shivam Tyagi

Powershell 命令 -

获取文件内容并将其替换为其他文本,然后存储到另一个文件中

命令 -1(获取内容文件名.xml)| ForEach-Object { $_.replace("some_text","replace_text").replace("some_other_text","replace_text") } |设置内容文件名2.xml

将另一个文件复制到原始文件中

命令2

Copy-Item -Path filename2.xml -Destination filename.xml -PassThru

删除另一个文件

命令 3

删除项目文件名 2.xml


h
halfer

Notepad++ 使用“在文件中查找”命令为您完成这一切。

https://i.stack.imgur.com/WrHHK.png

https://i.stack.imgur.com/VMpKL.png


您如何从脚本中使用它来自动执行任务?上次我查看时,notepad++ 没有随 Windows (Any built in functions?) 一起提供
许多人回答了最初的问题。我正在回复无数寻找解决方案的回复。 MINE 是一个明确的答案,也是一个从您的管理角度易于实施的解决方案:Notepad++ 是免费的并且运行良好。
我最近不得不在 robocopy 脚本中查找和替换嵌套的 cmd 文件,以添加多线程,最终在多个位置包含超过 60 个文件。 Notepad ++ 从根目录开始就做到了。它是免费的,具有 64 位支持,定期更新,并且不需要大量的编码来使用或每年至少花费 600 美元。优秀的管理编程解决方案。 notepad-plus-plus.org/downloads
N
Nadjib

在 Visual C++ 下编码时,我曾多次遇到过这个问题。如果你有它,你可以使用 Visual Studio 的查找和替换实用程序。它允许您选择一个文件夹并将该文件夹中任何文件的内容替换为您想要的任何其他文本。

在 Visual Studio 下:编辑 -> 查找和替换 在打开的对话框中,选择您的文件夹并填写“查找内容”和“替换为”框。希望这会有所帮助。


Nadjib,您的回答对用户没有帮助,因为您假设他们正在使用他们没有提及的软件。请建议一个不需要软件的选项。
@Aibrean 答案是没有用的,但不是因为这个原因,而是入口点是错误的。
这种回应不值得反对。在 Windows 环境中,没有很多好的选择可以解决 OP 的问题。我碰巧在 VS 中编写代码,发现这是一个很好的答案,并为我节省了大量时间寻找另一个解决方案。在不到一分钟的时间内替换了 3 个目录中超过 2k 个文件中的 20k+ 次出现。