Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am writing a batch file script using Windows command-line environment and want to change each occurrence of some text in a file (ex. "FOO") with another (ex. "BAR"). What is the simplest way to do that? Any built in functions?

share|improve this question
You might want to clarify that you mean "Windows command-line environment", not "MS-DOS". – bzlm Sep 26 '08 at 9:34
@bzlm, The command line in Windows since I believe Windows 2000 on up is not referred to as MS-DOS but instead just the Windows Command Prompt or Windows Command Line. – jpierson Sep 17 '10 at 1:55
@jpierson stackoverflow.com/posts/60034/revisions ;) – bzlm Sep 17 '10 at 7:33
2  
@jpierson You'll get there! – bzlm Sep 18 '10 at 9:03
1  
Simplly sw.ixoft.com/texfinderx – Mohsen Dec 12 '12 at 9:21
show 1 more comment

17 Answers

up vote 61 down vote accepted

If you are on Windows version that supports .Net 2.0, I would replace your shell. PowerShell gives you the full power of .Net from the command line. There are many commandlets built in as well. The example below will solve your question. I'm using the full names of the commands, there are shorter aliases, but this gives you something to Google for.

Get-Content test.txt | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test2.txt
share|improve this answer
2  
I can see PowerShell is capable of archieving this. But how can I make this run from a batch file (example: myProc.bat)? – Pablo Venturino Mar 3 '10 at 12:43
1  
@Pablo, use powershell.exe and wrap ps command into single parameter – lubos hasko Mar 5 '10 at 8:13
2  
Now Powershell is part of Windows as of Windows 7 so this really is a great option. – jpierson Sep 17 '10 at 1:52
4  
-1.. Sure the answer was accepted, but it's not answer to the specified question. – dave at flow May 2 '12 at 1:29
8  
This will fail with a file in use error if you save to the same file. You need to change the powershell command to: (Get-Content test.txt) | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test.txt – BigMomma Aug 29 '12 at 12:29
show 5 more comments

Just used FART ("F ind A nd R eplace T ext" command line utility):
excellent little freeware for text replacement within a large set of files.

The setup files are here.

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

will preview the replacements to recursively do in the files of this Perl distribution.

Only problem: the FART website icon isn't exactly tasteful, refined nor elegant ;)

share|improve this answer
7  
The cool thing is it's one single exe. No dependencies. No small prints. Super easy to deploy. – Serge - appTranslator Mar 2 '11 at 17:24
Thanks for the fart recommendation. Seems to work well, although I wish it supported regex. – Gary Kephart Jul 9 '11 at 16:57
Very lightweight and easy to use, but I was hoping it would print out the exact places that replacements took place. Not being able to see that gave me a sense of insecurity. – William Niu Sep 6 '11 at 7:39
1  
Thanks, it's perfect, should be part of the standard dos tools and worked a charm. The -p option however doesn't show you how many changes it 'would' make and always reports 0 which threw me for a few mins – sradforth Jan 10 '12 at 14:53
Very useful! (it's also very fast even on big files... like replacing all space with tab on 4Mb firewall log file (doing Excel analysis...)) – Max Oct 9 '12 at 15:51

BatchSubstitute.bat on dostips.com is an example of search and replace using a pure batch file.

It uses a combination of FOR, FIND and CALL SET.

Lines containing characters among "&<>]|^ may be treated incorrectly.


share|improve this answer
Awesome. Bliss. Greatfruit. – Kieveli Sep 15 '09 at 18:12
2  
I have to question the usefulness of a code snippet site whose terms of use prohibit copying any of the code (“You may not distribute any information provided under the domain dostips.com in any form without express written permission of the domain owner.”). – Gilles Apr 11 '12 at 8:34
I agree their terms are confusing, they also say "The information provided under the domain dostips.com is hopefully useful" so my assumption is that they are happy for people to copy the code to solve a problem. I'm not sure I have ever read any terms and conditions and been happy... – morechilli Apr 16 '12 at 9:58
3  
This is great. I love answers that don't involve downloading something else to do it. – Ruairi Jun 11 '12 at 9:42

Replace - Replace a substring using string substitution Description: To replace a substring with another string use the string substitution feature. The example shown here replaces all occurrences "teh" misspellings with "the" in the string variable str.

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

Script Output:

teh cat in teh hat
the cat in the hat

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

share|improve this answer
1  
the sed suggestion above is better – Bill Richardson May 28 '11 at 1:28
10  
How is the sed suggestion better? This seems to be the most simple answer of them all and requires installing nothing. – DonBecker Jan 20 '12 at 20:18
2  
Can any sort of pattern matching be done here? Wildcards, Regex etc? – Keyo Apr 19 '12 at 21:51
"How is the sed suggestion better?" - sed and similar utilities operate on files; this snippet omits the important step of reading lines from the input file and writing to the output file, while ensuring that any special characters in the file are handled correctly. – Joe Jun 13 at 11:25

I don't think there's a way to do it with any built-in commands. I would suggest you download something like Gnuwin32 or UnxUtils and use the sed command (or download only sed):

sed -c s/FOO/BAR/g filename
share|improve this answer
Use cygwin (cygwin.com). It's the next best thing to actually installing linux. – Andrew Johnson Sep 12 '08 at 22:12
It's better if one can provide a solution that doesn't rely on installing cygwin. POSIX string manipulation is a no-brainer - doing this on Windows is a little more obscure. – Rex Jul 17 '12 at 10:10
2  
Gnuwin32 and UnxUtils are stand-alone binaries built for Windows. They are not dependent on cygwin. – Ferruccio Jul 17 '12 at 11:47

Create file 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

To use this revised script (which we’ll call replace.vbs) just type a command similar to this from the command prompt:

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

share|improve this answer

Here's a solution that I found worked on Win XP. In my running batch file, I included the following:

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

The replace.bat file is as below. I did not find a way to include that function within the same batch file, because the %%a variable always seems to give the last value in the for loop.

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
share|improve this answer
Essentially the same as Bill Richardson's answer. – 0xC0000022L Apr 9 '12 at 20:39

I have used perl, and that works marvelously.

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

.orig is the extension it would append to the original file

For a number of files matching such as *.html

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

May be a little bit late, but I am frequently looking for similar stuff, since I don't want to get through the pain of getting software approved.

However, you usually use the FOR statement in various forms. Someone created a useful batch file that does a search and replace. Have a look here. It is important to understand the limitations of the batch file provided. For this reason I don't copy the source code in this answer.

share|improve this answer

Use fnr utility its better than fart since it can search and replace based on regular expressions. Also for the UI lovers you can configure options in UI and it can generate command line string which can then be used in your script. Very easy to use even as command line stirng.

Find it here http://findandreplace.codeplex.com/

Example fnr --cl --dir "" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"

share|improve this answer
This is nice. Being able to generate the command line from the gui is a nice simple feature that got me going quickly. – David Hammond Mar 15 at 19:40

I have written a small hybrid JScript/batch utility called REPL.BAT that is very convenient for modifying files via the command line or a batch file. The purely native script does not require installation of any 3rd party executeable, and it works on any modern Windows version from XP onward. It is also very fast, especially when compared to pure batch solutions.

REPL.BAT simply reads stdin, performs a JScript regex search and replace, and writes the result to stdout.

Here is a trivial example of how to replace foo with bar in test.txt, assuming REPL.BAT is in your current folder, or better yet, somewhere within your PATH:

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

The JScript regex capabilities make it very powerful, especially the ability of the replacement text to reference captured substrings from the search text.

I've included a number of options in the utility that make it quite powerful. For example, combining the M and X options enable modification of binary files! The M Multi-line option allows searches across multiple lines. The X eXtended substitution pattern option provides escape sequences that enable inclusion of any binary value in the replacement text.

The entire utility could have been written as pure JScript, but the hybrid batch file eliminates the need to explicitly specify CSCRIPT every time you want to use the utility.

Here is the REPL.BAT script. Full documentation is embedded within the script.

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

::************ Documentation ***********
:::
:::REPL  Search  Replace  [Options  [SourceVar]]
:::REPL  /?
:::
:::  Performs a global 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.
:::
:::  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.
:::
:::            I - Makes the search case-insensitive.
:::
:::            L - The Search is treated as a string literal instead of a
:::                regular expression. Also, all $ found in Replace are
:::                treated as $ literals.
:::
:::            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.
:::
:::            V - Search and Replace represent the name of environment
:::                variables that contain the respective values. An undefined
:::                variable is treated as an empty string.
:::
:::            M - Multi-line mode. The entire contents of stdin is read and
:::                processed in one pass instead of line by line. ^ anchors
:::                the beginning of a line and $ anchors the end of a line.
:::
:::            X - Enables extended substitution pattern syntax with support
:::                for the following escape sequences within the Replace string:
:::
:::                \\     -  Backslash
:::                \b     -  Backspace
:::                \f     -  Formfeed
:::                \n     -  Newline
:::                \r     -  Carriage Return
:::                \t     -  Horizontal Tab
:::                \v     -  Vertical Tab
:::                \xnn   -  Ascii (Latin 1) character expressed as 2 hex digits
:::                \unnnn -  Unicode character expressed as 4 hex digits
:::
:::                Escape sequences are supported even when the L option is 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.
:::

::************ Batch portion ***********
@echo off
if .%2 equ . (
  if "%~1" equ "/?" (
    findstr "^:::" "%~f0" | cscript //E:JScript //nologo "%~f0" "^:::" ""
    exit /b 0
  ) else (
    call :err "Insufficient arguments"
    exit /b 1
  )
)
echo(%~3|findstr /i "[^SMILEBVX]" >nul && (
  call :err "Invalid option(s)"
  exit /b 1
)
cscript //E:JScript //nologo "%~f0" %*
exit /b 0

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

************* JScript portion **********/
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 srcVar=(options.indexOf("s")>=0);
if (srcVar) {
  options=options.replace(/s/g,"");
}
if (options.indexOf("v")>=0) {
  options=options.replace(/v/g,"");
  search=env(search);
  replace=env(replace);
}
if (options.indexOf("l")>=0) {
  options=options.replace(/l/g,"");
  search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1");
  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+"$"
}
if (options.indexOf("x")>=0) {
  options=options.replace(/x/g,"");
  replace=replace.replace(/\\\\/g,"\\B");
  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,"\\");
}
var search=new RegExp(search,options);

if (srcVar) {
  WScript.Stdout.Write(env(args.Item(3)).replace(search,replace));
} else {
  while (!WScript.StdIn.AtEndOfStream) {
    if (multi) {
      WScript.Stdout.Write(WScript.StdIn.ReadAll().replace(search,replace));
    } else {
      WScript.Stdout.WriteLine(WScript.StdIn.ReadLine().replace(search,replace));
    }
  }
}
share|improve this answer
Great stuff! I love this b/c of the simplicity and the way you can adapt it to whatever script, hence writing JS code than crappy batch. – DotNetWise Jun 23 at 21:29

Take a look at http://stackoverflow.com/questions/127318/ which asked for a sed equivalent under Windows, should apply to this question as well. Executive summary:

  • It can be done in batch file, but it's not pretty
  • Lots of available third party executables that will do it for you, if you have the luxury of installing or just copying over an exe
  • Can be done with VBScript or similar if you need something able to run on a Windows box without modification etc.
share|improve this answer

I played around with some of the existing answers here and prefer my improved solution...

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

or if you want to save the output again to a file...

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

The benefit of this is that you can pipe in output from any program. Will look into using regular expressions with this too. Couldn't work out how to make it into a BAT file for easier use though... :-(

share|improve this answer

This is one thing that batch scripting just does not do well.

The script morechilli linked to will work for some files, but unfortunately it will choke on ones which contain characters such as pipes and ampersands.

VBScript is a better built-in tool for this task. See this article for an example: http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0208.mspx

share|improve this answer

When I was looking for a similar tool for my own usage, I found many of the tools lacking. So I wrote yet another one and made it open source. http://findandreplace.codeplex.com/

The main difference with other tools is that you can easily generate a command line using windows dialog and test it through regular UI before running find/replace in DOS or in batch file.

share|improve this answer

Power shell command works like a charm

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

Download Cygwin (free) and use unix-like commands at the Windows command line.

Your best bet: sed

share|improve this answer
7  
Cygwin is evil. Don't install it. Better use UnixUtils mentioned below. – zedoo Oct 20 '10 at 8:15
12  
What's so evil about it? – jm. Oct 21 '10 at 23:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.