How can you find and replace text in a file using the Windows command-line environment?
Solution 1
A lot of the answers here helped point me in the right direction, however none were suitable for me, so I am posting my solution.
I have Windows 7, which comes with PowerShell built-in. Here is the script I used to find/replace all instances of text in a file:
powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt"
To explain it:
-
powershell
starts up powershell.exe, which is included in Windows 7 -
-Command "... "
is a command line arg for powershell.exe containing the command to run -
(gc myFile.txt)
reads the content ofmyFile.txt
(gc
is short for theGet-Content
command) -
-replace 'foo', 'bar'
simply runs the replace command to replacefoo
withbar
-
| Out-File myFile.txt
pipes the output to the filemyFile.txt
-
-encoding ASCII
prevents transcribing the output file to unicode, as the comments point out
Powershell.exe should be part of your PATH statement already, but if not you can add it. The location of it on my machine is C:\WINDOWS\system32\WindowsPowerShell\v1.0
Update
Apparently modern windows systems have PowerShell built in allowing you to access this directly using
(Get-Content myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt
Solution 2
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
Solution 3
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 on SourceForge.
Usage example:
fart.exe -p -r -c -- C:\tools\perl-5.8.9\* @@APP_DIR@@ C:\tools
will preview the replacements to do recursively in the files of this Perl distribution.
Only problem: the FART website icon isn't exactly tasteful, refined or elegant ;)
Update 2017 (7 years later) jagb points out in the comments to the 2011 article "FARTing the Easy Way – Find And Replace Text" from Mikail Tunç
As noted by Joe Jobs in the comments (Dec. 2020), if you want to replace &A
for instance, you would need to use quotes in order to make sure &
is not interpreted by the shell:
fart in.txt "&A" "B"
Solution 4
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
Solution 5
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 "
Comments
-
Ray over 2 years
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?
-
Andrew Johnson over 15 yearsUse cygwin (cygwin.com). It's the next best thing to actually installing linux.
-
Steven Murawski over 15 yearsI second the vote for PowerShell. It gives you just an extremely capable shell.
-
Pablo Venturino about 14 yearsI can see PowerShell is capable of archieving this. But how can I make this run from a batch file (example: myProc.bat)?
-
lubos hasko about 14 years@Pablo, use powershell.exe and wrap ps command into single parameter
-
zedoo over 13 yearsCygwin is evil. Don't install it. Better use UnixUtils mentioned below.
-
Serge Wautier about 13 yearsThe cool thing is it's one single exe. No dependencies. No small prints. Super easy to deploy.
-
Gary Kephart almost 13 yearsThanks for the fart recommendation. Seems to work well, although I wish it supported regex.
-
William Niu over 12 yearsVery 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.
-
sradforth over 12 yearsThanks, 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
-
DonBecker over 12 yearsHow is the sed suggestion better? This seems to be the most simple answer of them all and requires installing nothing.
-
Gilles 'SO- stop being evil' about 12 yearsI 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.”).
-
Aleadam about 12 yearsI 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...
-
Benbob about 12 yearsCan any sort of pattern matching be done here? Wildcards, Regex etc?
-
baash05 about 12 years-1.. Sure the answer was accepted, but it's not answer to the specified question.
-
Simon East almost 12 yearsI posted another variation of Mike's answer where the data is piped into Powershell (see below).
-
Ruairi O'Brien almost 12 yearsThis is great. I love answers that don't involve downloading something else to do it.
-
Rex almost 12 yearsIt'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.
-
Ferruccio almost 12 yearsGnuwin32 and UnxUtils are stand-alone binaries built for Windows. They are not dependent on cygwin.
-
BigMomma over 11 yearsThis 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
-
Max over 11 yearsVery useful! (it's also very fast even on big files... like replacing all space with tab on 4Mb firewall log file (doing Excel analysis...))
-
David Hammond about 11 yearsThis is nice. Being able to generate the command line from the gui is a nice simple feature that got me going quickly.
-
lapis almost 11 yearsI'm trying to put this in a function but it doesn't work like that, neither does it show an error message. It just writes the same content. Could somebody please tell me what's wrong?
function Replace { (Get-Content $args[0]) | ForEach-Object { $_ -replace "$($args[1])", "$($args[2])" } | Set-Content $args[0] } Replace test.txt foo bar
-
Gus Leo almost 11 years@Psycho, It looks like you have an extra $() round your replacements... does the following work? function Replace { (Get-Content $args[0]) | ForEach-Object { $_ -replace "$args[1]", "$args[2]" } | Set-Content $args[0] }
-
lapis almost 11 years@Mike, that's the syntax (odd-looking, I agree) for referencing array elements in replacements, without it it prints the whole array and then the string "[1]" (or "[2]" respectively).
-
Joe almost 11 years"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.
-
Adaptabi almost 11 yearsGreat 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.
-
dbenham almost 11 yearsEdit - Added the A option to only print lines that have been modified. Also enhanced the X option to support
\q
to represent"
, and Search literals now support all the extended escape sequences when L and X options are combined. -
Pavel Hodek almost 11 yearsIn PowerShell v3 there is -Raw parameter for Get-Content which makes processing large files significantly faster (in my case 200 times faster). It reads the whole file as a string not as an array of lines.
-
Alexey Vishentsev almost 11 yearscygwin:
sed -i -b -e 's/FOO/BAR/g' `find . -name *.txt`
-i -- edit file inplace; -b -- do not process CR+LF - without this option CR+LF would be converted to LF -
Jahmic almost 11 yearsI also like solutions that don't involve external utilities, unfortunately, I keep getting "find: invalid predicate `'" when I try to run this batch. Don't really have the time to debug it right now.
-
Jahmic almost 11 yearsThe "find: invalid predicate `'" error was due to an external 'find' utility on my system. Once removed, this worked fine.
-
gareththegeek almost 11 yearsTechnically does not answer the original question, Powershell requires elevated privileges and may not be appropriate in all situations
-
b w over 10 years@dbenham - +1. This is a slick approach, it will come in handy for several other tasks as well. Thanks for posting it.
-
dbenham over 10 yearsEDIT - I modified behavior of \xnn when X option is used so that the code represents the extended ASCII byte code. Also added a /V version option.
-
Janis Veinbergs over 10 years@gareththegeek You have a false assumption. Powershell does not require elevated privileges. I'm saying this so that future readers know this.
-
Royi Namir over 10 yearsWhat if I want to replace the content in the same file ( and not save a new file) ?
-
Gus Leo over 10 years@royinamir: I would guess that the following untested code would work: Get-Content test.txt | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test.txt
-
Royi Namir over 10 years@MikeSchall No. file in use.
-
Gus Leo over 10 years@royinamir: Looks like putting parentheses around the get content might solve the problem? Sorry, no pc around to test on right now... stackoverflow.com/questions/10239702/…
-
user280109 over 10 yearsthis is neat, does it allow the use of RegEx?
-
Asad Saeeduddin about 10 years@Joe Wrong. You can pipe any output to sed, files are not necessary.
-
Joe about 10 years@Asad, yes that's true, the OP was asking about files, but in fact it works with streams which don't have to be files. But my point here is that this answer is flawed, since it omits reading/writing from a stream and handling any special characters.
-
Wyck about 10 yearsBeware, this command may also transcode the file to Unicode encoding. You can manually specify the encoding by adding
-encoding ASCII
orUTF8
or whatever is needed. Also beware, if you target UTF8, it may introduce a Byte Order Mark at the beginning of the file that did not appear in the original. -
MalTec about 10 years@Bill how to use variable as a replacing text? ie. I have value in a variable and a string which has some delimter. set str=%str:"##"=%varValue%% doesn't work. Any workarounds?
-
dbenham about 10 yearsEDIT - updated code to version 3.3: Option A can now be combined with M if S is also used. Also added new help options /?REGEX and /?REPLACE to automatically open relevant MicroSoft documentation in your browser.
-
Artur Kędzior about 10 yearsVery useful tool. Tried FART before but the documentation is out of date.
-
Reese almost 10 years@Wyck It took me a while to figure out where to put
-encoding ASCII
. For anyone needing it in the future, it would beOut-File -encoding ASCII myFile.txt
-
Toothbrush almost 10 years@user280109 Yes, VBScript supports
RegExp
. You can use this to replace using a regular expression:With (New RegExp): strNewText = .Replace(strText, strOldText, strNewText): End With
. You can get the text of the first 9 capturing groups using$1
,$2
...$9
. -
dbenham almost 10 yearsEDIT - updated code to version 4.0. Option N added to enable reading binary files containing NULL bytes. This is a work-around to a bug with
WScript.StdIn.ReadAll()
. See dostips.com/forum/viewtopic.php?p=36033#p36033 -
dbenham almost 10 yearsEDIT - updated code to v4.1. Option N removed. M option now always works properly with binary files. Also improved performance with binary files.
-
Dio Phung over 9 yearsCool tool,it even supports regular expression. This is something that FART is missing.
-
dbenham over 9 yearsEDIT - updated code to v5.0 - Refined and documented return codes. You can now tell whether REPL.BAT makes a change to the data or not.
-
dbenham over 9 yearsEDIT - updated code to v6.0 - Added J option to specify replacement value as a JScript expression. See dostips.com/forum/viewtopic.php?p=37855#p37855 for details and examples.
-
dbenham over 9 yearsEDIT - updated code to v6.2 - Bug fix - $ should not be escaped in Replace if J option used. Also corrected description of A option.
-
kurtzmarc over 9 yearsThe only thing I had to change was to use
Set-Content
instead ofOut-File
. -
sirdank about 9 yearsThis is a good solution. Unfortunately, using
type
means all lines greater than 80 characters get wrapped. What a pain. -
Aibrean about 9 yearsNadjib, your answer doesn't help the user because your assuming they are using software of which they make no mention. Please suggest an option that doesn't require software.
-
Nigel Touch about 9 yearsSee the answer from @Rachel:
powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | sc myFile.txt"
-
Gras Double about 9 yearsThanks for indicating this tool. Single exe, great replacement for FART which is no longer developed (and misses regex); and PowerShell syntax is sooo unbearable.
-
Serban Tanasa about 9 yearsThis is most useful. Was looking for grep+sed replacement in windows, this worked great!
-
Andrew almost 9 years@MalTec, I am just trying that, to place some text with
%s
, but I couldn't do it so far. I could kind of escape it in an echo command with^
but not in a set command. -
jsuddsjr almost 9 yearsThis works, but the performance is terrible on even a short list of files.
-
Admin almost 9 yearsThank you for actually answering what the OP asked for - something that's simple and in-built to the CMD shell.
-
Paul almost 9 years@Aibrean the answer is no use, but not for that reason, it's the entry point that is wrong.
-
Atif Aziz almost 9 years@dbenham This is a gem. Why don't you put it up on GitHub or as a Gist? Would make versioning, follow-ups, releases/distribution, fixes and more easier. If you need help with that, let me know.
-
John Rocha over 8 yearsSadly this also skips blank lines. A feature of the {{for}} command.
-
specializt about 8 yearsthe batch script does nothing but a mere file-copy - also : why are you thanking yourself?
-
Leptonator about 8 yearsThe original request was to replace "FOO" with "BAR" in a text file using a batch script and with preferably built-in functions. If anything I was thanking the Google Groups post I had found which works fantastic and we still use it to this day. Also, see posts and responses like these as being helpful for users coming down the road as well. I fail to see your comment about file copy.. Sure, it takes the content of one file and echo's the result into another file, but based on the data, it does trim and parse off the needed information. I would recommend giving it a try first. ;)
-
specializt about 8 yearsits basically a file-copy tool which replaces two static strings - you could've at least placed two variables in there so people who want to try it wont need to understand the syntax in order to actually be able to use it -- also : assumptions over the internet are almost always completely wrong. Remember that.
-
Leptonator about 8 yearsOK.. So, do you recommend my re-writing the code? And, if so, do you have some suggestions? I guess where I am at with this right now, is that it works. I see your point, but yet while it is using static variables, it does "deduplicate" which overcomes the major hurdle. While there are tools that accomplish the needs of this, using the native CMD addresses the need. I know that the Internet is not always trustworthy (hence the comment about being the "bathroom wall" and people will write most anything they want) - you have to test and verify and re-verify and be careful what we publish.
-
specializt about 8 yearswho is "we" and what is "static variable" supposed to mean - other than static object variables / members?
-
Leptonator about 8 years@specializt - Please... I am not here to debate semantics. If you like, can we take this offline into the chat room.
-
J W about 8 yearsBeware that the replace token ('foo' in this case) is treated as a regular expression. If you have any special characters there ( I had [ ] ), you need to prepend them with a \ (backslash).
-
pepan about 8 yearsTo escape special characters, one can also use 'foo-bar' (apostrophes) in the regular expression.
-
Naypa about 8 yearsOk, this replaces text in a environment variable, but how to use it to replace the content of a file?
-
ereOn about 8 yearsNote that if you are indeed doing that rename in a git repository and only want to replace in versionned files, you may want to do:
git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'
which works wonders. -
yzorg almost 8 yearsThis sounds like a good idea, but can be big waste of time (I would NOT recommend this for the inexperienced). If you skipped BAT/CMD FOR/IF because you need regex, then your match symbols could hit issues in any of the 4 layers of command interpolation: BAT, PowerShell.exe argument parsing, PowerShell script (inside parens), PowerShell command (outside parens -- yes, it's different). Warning: Out-File will change encoding to UTF-16. Try anything once, but if it doesn't work the first time don't even try to figure it out. Either embrace POSH (ditch CMD) or get a tool like
sed
. -
Yann39 almost 8 yearsThis is the simplest solution +1, when converting from sh to bat, just replace
sed
withperl -pi.backup -e
and appreciate it :) -
zelanix over 7 yearsVBScript is often overlooked (and hated on), but is available on all Windows platforms, is very readable and actually has very powerful capabilities +1
-
CaptainMarvel over 7 yearsHow would this be done for all files in dir of a given extension?
-
cxw about 7 years@AtifAziz Agreed! dbenham, any thoughts? I personally find full repos on github easier to work with than Gists, so that would be my vote.
-
jagb about 7 yearsI understand this is a very old question but I found more information and hope it will be helpful to Stack Overflow users. Just another link for FART where product is well explained: FART explaned @emtunc.org and another page can be found here: FART Please be careful with the replacement of
/
and'
as this is not working for all of us, for me it worked in some cases but it didn't work on some files and I don't know why.. I used this to replace text with other text and a/
-
carlossierra about 7 yearsOn a single file with close to 40.000 lines, performance was really good. Thanks for a great answer!
-
dbenham almost 7 years@Pogrindis - I hope you are using the newer JREPL.BAT instead of the outdated (superseded) REPL.BAT
-
dbenham almost 7 yearsFixed the link to JREPL.BAT
-
Ajmal PraveeN over 6 years@user280109 You just given the command, What i need. But i want to replace (case-insensitive) Can you provide the command for that?
-
GeeWhizBang over 6 yearsPowershell is more powerful, but boy does it suck anyway. I wish they'd done something more like 4DOS / Take Command
-
Cthutu over 5 yearsHow would you replace case-sensitively? I tried -creplace but that doesn't seem to work.
-
mico over 5 yearsIn my opinion, this is the answer to the original question. I will be using this tip to configure initialization files for a service during setup, and I would not want to enable PowerShell, or allow the scripting engine to run on my servers. So often answers to questions related to windows, start with "install this gizmo from there" as there is still a "PC" attitude around.
-
Florian Straub over 5 yearsIn case you want to use this in a loop one would need to use EnableDelayedExpansion like described at stackoverflow.com/questions/8281242/…
-
WEBjuju over 5 years@cthutu
-ireplace
is the case insensitive-replace
-
rugk about 5 yearsIt should be noted that by default the PowerShell execution is restricted, so you may not be able to run that by default on a system. You can easily disable this with another parameter for PowerShell however, see stackoverflow.com/a/9167524/5008962
-
Lovethenakedgun almost 5 yearsAnother issue with this vs a similar statement in the
sed
utility, is that the way it's written, it will read the entire source file into memory before doing a replacement. If you're using it on large files (e.g. MySQLDump) it will max out your system resources very quickly. Using something similar like,filter replace-strs { $_ -replace 'foo', 'bar' } if (test-path outFile.txt) { Clear-Content outFile.txt } Get-Content myFile.txt | replace-strs | Add-Content outFile.txt
should work line-by-line. -
Andry almost 5 years@jm May be because you have to install the whole thing together instead of use a single executable whenever you want to.
-
Benjamin Bihler over 4 yearsBefore Windows users immediately do file swapping: newer versions of sed support in-place editing with
-i
! If your sed version does, then check the command from this answer: stackoverflow.com/a/33762001/2492801. -
Simon East over 4 yearsTip: If your filenames have spaces within them, you need to surround them in single quotes.
-
Simon East over 4 yearsImportant: Unless you really want to use regular expressions, you should disable
foo
andbar
from being treated as regex (which often causes issues). To do this you modify the script slightly from(gc 'myFile.txt') -replace 'foo', 'bar'
to(gc 'myFile.txt').replace('foo', 'bar')
-
Preza8 over 4 years@AndrewJohnson Opinion and information are two different things.
-
Preza8 over 4 yearsBetter use powershell, it is actually built-in in windows.
-
Adam Jagosz about 4 yearsThis worked for me but suddenly stopped after I changed the filenames, without any error messages. The files are saved, but the strings are not replaced. I'm going crazy here.
-
srk almost 4 yearsTo find/replace special characters (like newline (
\n
) or tab (\t
)), use double quotes and a backtick. For example, to replace spaces with tabs:-replace ' ', "`t"
. -
Jason over 3 yearsThis response does not deserve the downvotes. In a Windows environment, there aren't a lot of good options to solve the OP's problem. I happen to code in VS and found this to be an excellent answer, and saved me a ton of time hunting for another solution. Replaced 20k+ occurrences in over 2k files across 3 directories in less than a min.
-
Adir D over 3 yearsBest advantage in 'fart' that is releases the stomach
-
Joe Jobs over 3 yearsI used encoding UTF8 instead of encoding ASCII for my UTF-8 text file but it messed the file
-
Ali Poustdouzan almost 3 yearsThank you, This script was great, I love your prefix (str and obj word), I do the same, It's old but gold, It's make code more readable.
-
Patrick Burwell over 2 yearsYou forgot encoding: '(Get-Content test.txt) | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content -encoding Ascii test2.txt' The REAL question is whether you can use WILDCARDS: '(Get-Content *.cmd) | ForEach-Object { $_ -replace "mt:32", "mt:128" } | Set-Content -encoding Ascii *.cmd'
-
jeb over 2 yearsAnd how do you use it from a script, to automate a task? And last time I looked, notepad++ wasn't shipped with windows (
Any built in functions?
) -
Patrick Burwell over 2 yearsThe original question was answered, by many. I was responding to the myriad of replies looking for a SOLUTION. MINE is a definitive ANSWER and a solution that is easy to implement from your administration point: Notepad++ is FREE and works very well.
-
Patrick Burwell over 2 yearsI recently had to find and replace nested cmd files in a robocopy script to add multithreading that ended up being over 60 files in multiple locations. Notepad ++ did it ALL in moments from the root. It's free, has 64 bit support, get's updated regularly, and does not require ridiculous amounts of coding to use or cost 600$ minimum/year. EXCELLENT admin programming solutions. notepad-plus-plus.org/downloads
-
tim99 over 2 yearscan you escape double quotes in the strings? like: cscript replace.vbs "C:\Scripts\Text.txt" "Jim says "hi" to you " "James says "hy" to you " so the result would be: Jim says "hi" to you --> James says "hy" to you
-
Patrick Burwell over 2 yearsCygwin has known issues. DO NOT USE.
-
HackerDaGreat57 about 2 yearsThanks a bunch! Much much faster than Notepad++...
-
Andrey Kazak about 2 yearsFind And Replace Text v1.99b: fart --c-style --quiet --preview "out.txt" "\\/" "/" outputs the input file contents to the stdio / stderr instead of showing the replace information for a 25 MB file. Opened a bug ticket @ sourceforge.net/p/fart-it/bugs/15.
-
Andrey Kazak about 2 yearsGreat tool for replacing FART. However, unfortunately, findandreplace.io/contact-us tells: The support for
Find & Replace
is currently paused.