我正在使用Windows命令行環境編寫批處理文件腳本,並但願用另外一個文件(例如「 BAR」)更改文件中每一個文本(例如「 FOO」)的每次出現。 最簡單的方法是什麼? 有內置功能嗎? php
我在這裏嘗試了一些現有的答案,而且更喜歡改進的解決方案... git
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文件以便於使用的問題... :-( shell
使用fnr
實用程序。 與fart
相比,它有一些優勢: express
在此處下載FNR: http : //findandreplace.io/? z = codeplex app
使用示例: fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"
less
注意 -請確保在此答案的末尾看到更新,以獲取指向取代REPL.BAT的高級JREPL.BAT的連接
JREPL.BAT 7.0及更高版本自己經過/UTF
選項支持Unicode(UTF-16LE),以及經過ADO !!!!支持的任何其餘字符集,包括UTF-8! ide
我編寫了一個名爲REPL.BAT的小型JScript /批處理混合實用程序 ,它很是方便經過命令行或批處理文件修改ASCII(或擴展ASCII)文件。 純本地腳本不須要安裝任何第三方可執行文件,而且能夠在XP之後的任何現代Windows版本上運行。 它也很是快,特別是與純批處理解決方案相比。 工具
REPL.BAT只需讀取stdin,執行JScript regex搜索和替換,而後將結果寫入stdout。 post
這是一個簡單的示例,說明如何將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的全部相同功能,而且還有更多功能:
與往常同樣,完整文檔嵌入在腳本中。
原始的簡單解決方案如今更加簡單:
jrepl "foo" "bar" /f test.txt /o -
JREPL.BAT的當前版本在DosTips上可用 。 閱讀該線程中的全部後續文章,以查看用法示例和開發歷史。
可能有點晚了,可是我常常在尋找相似的東西,由於我不想擺脫得到軟件批准的痛苦。
可是,您一般以各類形式使用FOR語句。 有人建立了一個有用的批處理文件來進行搜索和替換。 在這裏看看。 重要的是要了解提供的批處理文件的限制。 所以,我不會在此答案中複製源代碼。
看看是否有cmd.exe的sed類實用程序在Windows下要求等效的sed,也應適用於此問題。 執行摘要: