首页 资讯频道 互联频道 智能频道 网络 数据频道 安全频道 服务器频道 存储频道

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

2020-02-26 11:18:06 来源 : 开源中国

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

#1楼

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

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

#2楼

使用FNR

使用fnr实用程序。 与fart相比,它有一些优点:

常用表达

可选的GUI。 具有“生成命令行按钮”以创建命令行文本以放入批处理文件中。

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

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

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

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

#3楼

注意 -请确保在此答案的末尾看到更新,以获取指向取代REPL.BAT的高级JREPL.BAT的链接

JREPL.BAT 7.0及更高版本本身通过/UTF选项支持Unicode(UTF-16LE),以及通过ADO !!!!支持的任何其他字符集,包括UTF-8!

我编写了一个名为REPL.BAT的小型JScript /批处理混合实用程序 ,它非常方便通过命令行或批处理文件修改ASCII(或扩展ASCII)文件。 纯本地脚本不需要安装任何第三方可执行文件,并且可以在XP以后的任何现代Windows版本上运行。 它也非常快,特别是与纯批处理解决方案相比。

REPL.BAT只需读取stdin,执行JScr​​ipt regex搜索和替换,然后将结果写入stdout。

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

type test.txt|repl "foo" "bar" >test.txt.new

move /y test.txt.new test.txt

JScript regex功能使其功能非常强大,尤其是替换文本能够引用搜索文本中捕获的子字符串的功能。

我在实用程序中包含了许多选项,这些选项使其功能非常强大。 例如,结合使用M和X选项可以修改二进制文件! 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 -

JREPL.BAT的当前版本在DosTips上可用 。 阅读该线程中的所有后续文章,以查看用法示例和开发历史。

#4楼

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

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

#5楼

看看是否有cmd.exe的sed类实用程序在Windows下要求等效的sed,也应适用于此问题。 执行摘要:

可以在批处理文件中完成,但这不是很漂亮

如果您可以安装或仅复制一个exe文件,则有许多可用的第三方可执行文件将为您完成此操作

如果您需要能够在Windows框上运行而无需修改等内容,则可以使用VBScript或类似工具来完成。

相关文章

最近更新