Bathc - find and replace several strings (Quick as possible!)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Jcochran857
Posts: 3
Joined: 22 Feb 2019 17:11

Bathc - find and replace several strings (Quick as possible!)

#1 Post by Jcochran857 » 22 Feb 2019 17:28

Newbie here - need help quick (if possible!)

I am trying to find and replace strings within .dat files (basically text). I have a list of items I need found and the items I need to replace them with. I used a batch script I found online, which worked yesterday but doesn't work today! If anyone can help with this ASAP I am in desperate need of help very quickly.

"Find" "Replace"

"MAW01_Fugro_2018" "MAW01_BSW_Fugro_2018"
" " "_"
"Proc-R3" "Proc-R4"
"Proc-R2" "Proc-R3"
"Proc-R1" "Proc-R2"
"Proc/" "Proc-R1/"
"_FixedNav/" "/"
"_RAW_" "_"
"_ 0" "_0"
"X3618_01B_Proc-R1"
"X3622_001_Proc"
"X3622_001_01B_Proc"
"M3382_01A_Proc-R1"
"3600G_INFILL_01B_Proc-R1"
"M3485_001_01A_Proc"
"__" "_"
"RR_02ABC_Proc-R2" "RR_02ABC_Proc-R1"
"RR_02ABC_01_Proc-R2" "RR_02ABC_01_Proc-R1"
"RR_02D_01_Proc-R2" "RR_02D_01_Proc-R1"
"RR_02D_Proc-R2" "RR_02D_Proc-R1"
"RR_02E_Proc-R2" "RR_02E_Proc-R1"
"RR_02F_Proc-R2" "RR_02F_Proc-R1"

Here's the thing: I need to run this on about 20 files, but not all files I want to run this on will have every string within it. I need the script to find the string and replace, and if thee string does not exist, then don't do anything. Also, the string's must match EXACTLY to the ones in Quotes in order to replace.

Below is the batch file I found online, and basically copied and pasted for each string I needed to replace. (AGAINNOT WORKING TODAY, SAYING CANNOT FIND _.vbs, even though this worked last night!!!)

Code: Select all

setlocal

call :FindReplace "Find" "Replace" File.dat

exit /b 

:FindReplace <Find> <Replace> <file.dat>
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

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: Bathc - find and replace several strings (Quick as possible!)

#2 Post by Ed Dyreen » 22 Feb 2019 20:48

I do not see what is wrong with that vbs, but If you do the main part in vbs, you might just as well do it all in vbs, I wonder why people wrap vbs scripts in a batch when both languages can do the job without each others help.

Convention is that languages are physically separated from each other unless there is some very good reason not to. Next code consists of 2 files in their appropriate language according to extension. The .vbs can then remain abstract so it can be reused in another context.

Try this, but backup your data cus it's been a year I wrote any vbs.

Code: Select all

Public oFSO : Set oFSO = CreateObject( "Scripting.FileSystemObject" )

Public Const FOR_READING 			= 1
Public Const FOR_WRITING 			= 2
Public Const TRISTATE_ASCII 		= 0 	' Opens the file as ASCII.

sMatch = WScript.Arguments(0)
sReplace = WScript.Arguments(1)
sFile = WScript.Arguments(2)

Set oFSOFile = oFSO.GetFile( sFile )

Set oTextStream = oFSOFile.OpenAsTextStream( FOR_READING, TRISTATE_ASCII )
sReadLines = oTextStream.readAll()
oTextStream.Close

Set oTextStream = oFSOFile.OpenAsTextStream( FOR_WRITING, TRISTATE_ASCII )
oTextStream.write( Replace( sReadLines, sMatch, sReplace ) )
oTextStream.Close
Note that wscript.arguments method does not support double quotes.

Code: Select all

@echo off

cscript.EXE //noLogo "replace.VBS"  "Find" "Replace" "File.dat"

pause &exit
This is only for small files, all data is read into memory, for larger files a line by line method similar to your code should be used, but I would again do it in batch or vbs not both.

Hope this works for you.

Dave Benham publiced a replace jscript but I wouldn't know how to use it. It is a hybrid batch.

Jcochran857
Posts: 3
Joined: 22 Feb 2019 17:11

Re: Bathc - find and replace several strings (Quick as possible!)

#3 Post by Jcochran857 » 22 Feb 2019 21:10

Honestly I'll take ANY solution at this point, doesn't have to be this batch file, could be one that runs more efficiently? ANY BATCH which will perform the task. I have no clue what to write honestly.

Also, I fforgot to add the information specified in this forum- see below

Code: Select all

 INFO.BAT version 1.5
--------------------------------------------------------------------------------
Windows version        :  Microsoft Windows [Version 10.0.14393]
Product name           :  Windows 10 Enterprise, 64 bit
Performance indicators :  Processor Cores: 8      Visible RAM: 33457352 kilobytes

Date/Time format       :  (mm/dd/yy)  Fri 02/22/2019  22:09:21.46
__APPDIR__             :  C:\WINDOWS\system32\
ComSpec                :  C:\WINDOWS\system32\cmd.exe
PathExt                :  .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
Extensions             :  system: Enabled   user: Enabled 
Delayed expansion      :  system: Disabled  user: Disabled
Locale name            :  en-US       Code Pages: OEM  437    ANSI 1252
DIR  format            :  02/22/2019  05:51 PM    51,539,607,552 pagefile.sys
Permissions            :  Elevated Admin=No, Admin group=Yes

                          Missing from the tool collection:  debug

Jcochran857
Posts: 3
Joined: 22 Feb 2019 17:11

SOLUTION!

#4 Post by Jcochran857 » 23 Feb 2019 00:26

I figured out I that I wasn't defining :MakeReplace location and files at the end of the script...

On a side note, I would REALLY love an explanation or solution on how to run this more efficiently? Like I stated in original post, I have several strings within several documents. I know using wildcard * will work to run through all documents, but not sure how to compile a "list" of strings and their associated replacements. Thanks for the quick reply regardless!

setlocal

:FindReplace <M3708D_MIG> <M3701D_MIG> <*.dat>
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

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: SOLUTION!

#5 Post by Ed Dyreen » 23 Feb 2019 09:31

Jcochran857 wrote:
23 Feb 2019 00:26
I figured out I that I wasn't defining :MakeReplace location and files at the end of the script...
I suspected something like that :)
Jcochran857 wrote:
23 Feb 2019 00:26
On a side note, I would REALLY love an explanation or solution on how to run this more efficiently?
Even the most efficient batch algorithm will be slow, vbs is notoriously slow with String operations but still much faster than batch. jscript does not have this problem. It also depends on the context. One algorithm will slow down tremendously when file size grows( read entire file at once), while another will be slower when there are many small files( replace line by line ). I suggest you download vbsedit freeware if you want to go that way, it is so rich in examples, snippets and help that you can learn vbs and js completely offline.

Oh one last thing, many people hate DEMANDING SOMETHING
(Quick as possible!)
Some may decide to not reply at all because they may feel you are being arrogant.
We do this for free at our own expense, don't forget that.

Post Reply