32

I have written a batch script to replace a string in text file.

Following is the script.

@echo off &setlocal
set "search=%1"
set "replace=%2"
set "textfile=Input.txt"
set "newfile=Output.txt"
(for /f "delims=" %%i in (%textfile%) do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    set "line=!line:%search%=%replace%!"
    echo(!line!
    endlocal
))>"%newfile%"
del %textfile%
rename %newfile%  %textfile%

But for a 12MB file, it is taking close to 7 min. I want it to be under a minute. Can we make use of find or findstr command to reduce the time taken?

Cœur
  • 37,241
  • 25
  • 195
  • 267
ananth joshi
  • 747
  • 3
  • 9
  • 11
  • Would you mind, telling the different times, theat the different solutions need for your 12MB file? Just to feed my curiosity. – Stephan Apr 16 '14 at 11:58
  • 1
    I don't think batch file is good for such high performance requirements. Use other scripting languages like python, perl, ruby... instead – phuclv Sep 11 '16 at 06:12
  • Why You Did not Use Notepad++ ? –  Aug 06 '19 at 10:12

6 Answers6

29

Give this a shot:

@echo off
setlocal

call :FindReplace "findstr" "replacestr" input.txt

exit /b 

:FindReplace <findstr> <replstr> <file>
set tmp="%temp%\tmp.txt"
If not exist %temp%\_.vbs call :MakeReplace
for /f "tokens=*" %%a in ('dir "%3" /s /b /a-d /on') do (
  for /f "usebackq" %%b in (`Findstr /mic:"%~1" "%%a"`) do (
    echo(&Echo Replacing "%~1" with "%~2" in file %%~nxa
    <%%a cscript //nologo %temp%\_.vbs "%~1" "%~2">%tmp%
    if exist %tmp% move /Y %tmp% "%%~dpnxa">nul
  )
)
del %temp%\_.vbs
exit /b

:MakeReplace
>%temp%\_.vbs echo with Wscript
>>%temp%\_.vbs echo set args=.arguments
>>%temp%\_.vbs echo .StdOut.Write _
>>%temp%\_.vbs echo Replace(.StdIn.ReadAll,args(0),args(1),1,-1,1)
>>%temp%\_.vbs echo end with
Matt Williamson
  • 6,947
  • 1
  • 23
  • 36
  • 3
    That's great! Pity it doesn't support unicoded files though. – Clox Nov 16 '14 at 03:43
  • 1
    This works for me! Why does it put a lock next to the file name though in windows explorer? – Merr Leader Mar 09 '15 at 18:54
  • awesome! thanks for the neat code, even someone with near to none knowledge about creating batch files can execute this without any issues. – Mina Jacob Mar 15 '17 at 02:44
  • This is what I have been looking for. Awesome stuff. Thanks for the code J – Shiva Krishna Chippa Mar 27 '17 at 19:13
  • This is great. How do you replace text that has double quotes in the argument? – tzg Sep 21 '17 at 17:39
  • Hi! How can I make this recursive? I tried to replace several identical files in different folders without success. Apparently it does not replace the text when there are more files in the folder. But it does replace it when there is only that one file. – MrEduar Jan 09 '21 at 19:09
11

Just download fart (find and replace text) from here

use it in CMD (for ease of use I add fart folder to my path variable)

here is an example:

fart -r "C:\myfolder\*.*" findSTR replaceSTR

this command will search in C:\myfolder and all sub-folders and replace findSTR with replaceSTR

-r means process sub-folders recursively.

fart is really fast and easy

farhad.kargaran
  • 2,233
  • 1
  • 24
  • 30
9

A variant using Bat/Powershell (need .net framework):

replace.bat :

@echo off

call:DoReplace "Findstr" "replacestr" test.txt test1.txt
exit /b

:DoReplace
echo ^(Get-Content "%3"^) ^| ForEach-Object { $_ -replace %1, %2 } ^| Set-Content %4>Rep.ps1
Powershell.exe -executionpolicy ByPass -File Rep.ps1
if exist Rep.ps1 del Rep.ps1
echo Done
pause
SachaDee
  • 9,245
  • 3
  • 23
  • 33
6

This uses a helper batch file called repl.bat - download from: https://www.dropbox.com/s/qidqwztmetbvklt/repl.bat

Place repl.bat in the same folder as the batch file or in a folder that is on the path.

Repl.bat is a hybrid batch file using native Windows scripting and is far faster than a regular batch script.

The L switch makes the text search and replace a literal string and I'd expect the 12 MB file to complete in several seconds on a modern PC.

@echo off &setlocal
set "search=%~1"
set "replace=%~2"
set "textfile=Input.txt"
set "newfile=Output.txt"
call repl.bat "%search%" "%replace%" L < "%textfile%" >"%newfile%"
del "%textfile%"
rename "%newfile%" "%textfile%"
foxidrive
  • 40,353
  • 10
  • 53
  • 68
  • Need a mirror for that repl.bat script!! – William Oliver Apr 12 '16 at 14:01
  • 1
    @WilliamOliver ROFL! Thanks for the heads up - that account has 7 batch scripts and a small 140 KB zip file. I've asked to see the traffic statistics to see why the sharing was disabled - I didn't receive any alert about it and apparently it's generating over 20 GB or 100,000 downloads a day for the sharing to be disabled. ;) Find two of the scripts here: Repl.bat: http://www.dostips.com/forum/viewtopic.php?f=3&t=3855 and Jrepl.bat: http://www.dostips.com/forum/viewtopic.php?f=3&t=6044 – foxidrive Apr 13 '16 at 08:53
  • @WilliamOliver Dropbox has finally told me that the Aacini_tools.zip had a malware flag raised on it. It's a false positive from a few Heuristic scans - the file has been on Dropbox servers for 2.5 years. I was required to delete the file and the account should be reactivated soon. Just following up here. – foxidrive Apr 20 '16 at 05:01
4

How about this?

set search=%1
set replace=%2
set textfile=Input.txt    

python -c "with open('%textfile%', 'rw') as f: f.write(f.read().replace('%search%', '%replace%'))"

Muhahaha

Barney Szabolcs
  • 11,846
  • 12
  • 66
  • 91
4

Try this:

@echo off &setlocal
setlocal enabledelayedexpansion

set "search=%1"
set "replace=%2"
set "textfile=Input.txt"
set "newfile=Output.txt"
(for /f "delims=" %%i in (%textfile%) do (
    set "line=%%i"
    set "line=!line:%search%=%replace%!"
    echo(!line!
))>"%newfile%"
del %textfile%
rename %newfile%  %textfile%
endlocal
One D.
  • 41
  • 1
  • 2
    This is nearly exactly the same script like the OP ones, but this destroys exclamation marks – jeb Feb 24 '16 at 10:25