简体   繁体   中英

How can you find and replace text in a file using the Windows command-line environment?

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?

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 of myFile.txt ( gc is short for the Get-Content command)
  • -replace 'foo', 'bar' simply runs the replace command to replace foo with bar
  • | Out-File myFile.txt | Out-File myFile.txt pipes the output to the file myFile.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

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

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" 

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

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 "

["

Note<\/em><\/strong> - Be sure to see the update at the end of this answer for a link to the superior JREPL.BAT that supersedes REPL.BAT<\/em><\/i>


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

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.


Use FNR

Use the fnr utility. It's got some advantages over fart :

  • Regular expressions
  • Optional GUI. Has a "Generate command line button" to create command line text to put in batch file.
  • Multi-line patterns: The GUI allows you to easily work with multi-line patterns. In FART you'd have to manually escape line breaks.
  • Allows you to select text file encoding. Also has an auto detect option.

Download FNR here: http://findandreplace.io/?z=codeplex

Usage example: fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"

I know I am late to the party..

Personally, I like the solution at: - http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace

We also, use the Dedupe Function extensively to help us deliver approximately 500 e-mails daily via SMTP from: - https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o

and these both work natively with no extra tools or utilities needed.

REPLACER:

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 (note the use of -9 for an ABA number):

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

Thanks!

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

When you work with Git on Windows then simply fire up git-bash and use sed . Or, when using Windows 10, start "Bash on Ubuntu on Windows" (from the Linux subsystem) and use sed .

Its a stream editor, but can edit files directly by using the following command:

sed -i -e 's/foo/bar/g' filename
  • -i option is used to edit in place on filename.
  • -e option indicates a command to run.
    • s is used to replace the found expression "foo" with "bar" and g is used to replace any found matches.

Note by ereOn:

If you want to replace a string in versioned files only of a Git repository, you may want to use:

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

which works wonders.

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... :-(

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

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

With the replacer.bat

1) With e? option that will evaluate special character sequences like \n\r and unicode sequences. In this case will replace quoted "Foo" and "Bar" :

call replacer.bat "e?C:\content.txt" "\u0022Foo\u0022" "\u0022Bar\u0022"

2) Straightforward replacing where the Foo and Bar are not quoted.

call replacer.bat "C:\content.txt" "Foo" "Bar"

Take a look at Is there any sed like utility for cmd.exe 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.

Two batch files that supply search and replace functions have been written by Stack Overflow members dbenham and aacini using native built-in jscript in Windows.

They are both robust and very swift with large files compared to plain batch scripting, and also simpler to use for basic replacing of text. They both have Windows regular expression pattern matching.

  1. This sed-like helper batch file is called repl.bat (by dbenham).

    Example using the L literal switch:

     echo This is FOO here|repl "FOO" "BAR" L echo and with a file: type "file.txt" |repl "FOO" "BAR" L >"newfile.txt"
  2. This grep-like helper batch file is called findrepl.bat (by aacini).

    Example which has regular expressions active:

     echo This is FOO here|findrepl "FOO" "BAR" echo and with a file: type "file.txt" |findrepl "FOO" "BAR" >"newfile.txt"

Both become powerful system-wide utilities when placed in a folder that is on the path , or can be used in the same folder with a batch file, or from the cmd prompt.

They both have case-insensitive switches and also many other functions.

Power shell command works like a charm

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

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.

I'm prefer to use sed from GNU utilities for Win32 , the followings need to be noted

  • single quote '' won't work in windows, use "" instead
  • sed -i won't work in windows, it will need file swapping

So the working code of sed to find and replace text in a file in windows is as below

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

Just faced a similar problem - "Search and replace text within files", but with the exception that for both filenames and search/repalce I need to use regex. Because I'm not familiar with Powershell and want to save my searches for later use I need something more "user friendly" (preferable if it has GUI).

So, while Googling :) I found a great tool - FAR (Find And Replace) (not FART).

That little program has nice GUI and support regex for searching in filenames and within files. Only disadventage is that if you want to save your settings you have to run the program as an administrator (at least on Win7).

Use powershell in .bat - for Windows 7+

encoding utf8 is optional, good for web sites

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

@Rachel gave an excellent answer but here is a variation of it to read content to a powershell $data variable. You may then easily manipulate content multiple times before writing to a output file. Also see how multi-line values are given in a .bat batch files.

@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%"

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

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

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

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

Your best bet: sed

Can also see the Replace and ReplaceFilter tools at https://zoomicon.github.io/tranXform/ (source included). The 2nd one is a filter.

The tool that replaces strings in files is in VBScript (needs Windows Script Host [WSH] to run in old Windows versions)

The filter is probably not working with Unicode unless you recompile with latest Delphi (or with FreePascal/Lazarus)

Powershell Command -

Getting content of the file and replacing it with some other text and then storing into another file

Command -1 (Get-Content filename.xml)| ForEach-Object { $_.replace("some_text","replace_text").replace("some_other_text","replace_text") } | Set-Content filename2.xml

Copying another file into the original one file

Command2

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

removing another one file

Command 3

Remove-Item filename2.xml

If you want to be really efficient and avoid these long line PowerShell commands, then SED is your friend, even on Windows. Just install GnuWin32 tools:

sed -i 's/foo/far/g' *.txt

Notepad++ does this ALL for you with the "Find in files" command.

在此处输入图像描述

在此处输入图像描述

I have faced this problem several times while coding under Visual C++. If you have it, you can use Visual studio Find and Replace Utility. It allows you to select a folder and replace the contents of any file in that folder with any other text you want.

Under Visual Studio: Edit -> Find and Replace In the opened dialog, select your folder and fill in "Find What" and "Replace With" boxes. Hope this will be helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM