Windows batch script to edit existing files

Hello all.  I need a batch script that can do the following...

Search in the directory c:\program files\bquest\

1) Find any and all files called "config.cfg" (basically a text file) in directory and subdirectories
2) Find 3 lines in the file, delete them individually, and then add 3 new lines to the file

exact lines to be deleted...
com_hunkmegs "56"
com_soundmegs "24"
com_zonemegs "24"

exact lines to be added (only if lines above were found and deleted)
com_hunkmegs "192"
com_soundmegs "32"
com_zonemegs "32"

There should be no output, and no error message if it can not find the exact lines to be deleted. If these exact line values are not found...the new lines should NOT be added to the file.  

Thanks in advance!!
icecom4Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Do you always require ALL 3 lines to be there, or is each line to be considered and replaced individually?
Would it be ok to just replace the contents line by line, with a 3rd-party tool?
0
icecom4Author Commented:
Also, i tried to edit but you replied too quickly for me.  There are five lines to be edited actually...

No 3rd party tools please, all in 1 batch...

And actually, I am ok with simply deleting all the lines and replacing with the lines below it.  It might be a nightmare to do otherwise.  

delete values starting with...
seta com_hunkmegs
seta com_soundmegs
seta com_zonemegs
seta seta cl_punkbuster
seta cl_punkbuster

replace with new line and values...
seta com_hunkmegs "192"
seta com_soundmegs "32"
seta com_zonemegs "32"
seta seta cl_punkbuster "1"
seta cl_punkbuster "1"
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
One question left is, and let me try to be more explicit this time:
If «seta com_hunkmegs» is found, delete it and append «seta com_hunkmegs "192"»
and the same for each of the 5 lines individually.
OR
Only if all 5 lines are found, "replace" them.
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

icecom4Author Commented:
Yes, replace.  Will the value also get deleted after seta com_hunkmegs for example?  Because these values change and I dont want value left over by itself.  
0
icecom4Author Commented:
and this is each line...not only if all 5 are found
0
Bill PrewIT / Software Engineering ConsultantCommented:
Here's a VB script approach.  It reads the file specified on the command line and does the replaces you want. It then either rewrites over the same file, or can write to a new file, useful for testing.  So you could run it as one of these approaches:

cscript EE27510872.vbs "c:\program files\bquest\config.sys"

or

cscript EE27510872.vbs "c:\program files\bquest\config.sys" "c:\program files\bquest\config.txt"


' Define needed constants
Const ForReading = 1
Const ForWriting = 2
Const TriStateUseDefault = -2

' Get input file name from command line parm, if 2 parms entered
' use second as new output file, else rewrite to input file
If (WScript.Arguments.Count > 0) Then
  sInfile = WScript.Arguments(0)
Else
  WScript.Echo "No filename specified."
  WScript.Quit
End If
If (WScript.Arguments.Count > 1) Then
  sOutfile = WScript.Arguments(1)
Else
  sOutfile = sInfile
End If

' Create file system object
Set oFSO = CreateObject("Scripting.FileSystemObject")

' Read entire input file into a variable and close it
Set oInfile = oFSO.OpenTextFile(sInfile, ForReading, False, TriStateUseDefault)
arrLines = Split(oInFile.ReadAll, vbCrLf)
oInfile.Close
Set oInfile = Nothing

For i = 0 To UBound(arrLines)
   If LCase(Trim(arrLines(i))) = "seta com_hunkmegs"       Then arrLines(i) = "seta com_hunkmegs ""192"""
   If LCase(Trim(arrLines(i))) = "seta com_soundmegs"      Then arrLines(i) = "seta com_soundmegs ""32"""
   If LCase(Trim(arrLines(i))) = "seta com_zonemegs"       Then arrLines(i) = "seta com_zonemegs ""32"""
   If LCase(Trim(arrLines(i))) = "seta seta cl_punkbuster" Then arrLines(i) = "seta seta cl_punkbuster ""1"""
   If LCase(Trim(arrLines(i))) = "seta cl_punkbuster"      Then arrLines(i) = "seta cl_punkbuster ""1"""
Next

' Write file with any changes made
Set oOutfile = oFSO.OpenTextFile(sOutfile, ForWriting, True)
oOutfile.Write(Join(arrLines, vbCrLf))
oOutfile.Close
Set oOutfile = Nothing

' Cleanup and end
Set oFSO = Nothing
Wscript.Quit

Open in new window


Keep in mind the Program Files folder on Windows Vista or Windows 7 is typically protected, and so the script would have to be run in administrative mode on those.

~bp
0
icecom4Author Commented:
I do not know much about vbs, does the average windows user have everything ready to run such a file?

Also, do I just copy and paste all this into a file called whatever.vbs?

Sorry, this is my first attempt at using a vbs file.  

Also, a batch solution is still welcome :D
0
Bill PrewIT / Software Engineering ConsultantCommented:
==> I do not know much about vbs, does the average windows user have everything ready to run
==> such a file?

Yes.

==> Also, do I just copy and paste all this into a file called whatever.vbs?

Yes.

~bp
0
Bill PrewIT / Software Engineering ConsultantCommented:
Are there any blank lines in the file?

~bp
0
Bill PrewIT / Software Engineering ConsultantCommented:
Getting late here, but here's a quick shot at a BAT approach.  Save it as a BAT file, and run it like:

EE27510872.bat "c:\program files\bquest\config.sys"


@echo off
setlocal EnableDelayedExpansion

if "%~1" == "" (
  echo ERROR - No source file spcified.
  exit /b 1
)
set InFile=%~1

set OutFile=%TEMP%\_temp_.txt

if exist "%OutFile%" del "%OutFile%"

for /F "usebackq tokens=*" %%A in ("%InFile%") do (
  set OutData=%%A
  if /I "%%A" == "seta com_hunkmegs"       set OutData=seta com_hunkmegs "192"
  if /I "%%A" == "seta com_soundmegs"      set OutData=seta com_soundmegs "32"
  if /I "%%A" == "seta com_zonemegs"       set OutData=seta com_zonemegs "32"
  if /I "%%A" == "seta seta cl_punkbuster" set OutData=seta seta cl_punkbuster "1"
  if /I "%%A" == "seta cl_punkbuster"      set OutData=seta cl_punkbuster "1"
  echo !OutData!
)>>"%OutFile%"

if exist "%OutFile%" (
  copy /Y "%OutFile%" "%Infile%
  del "%OutFile%"
)

Open in new window

~bp
0
icecom4Author Commented:
I don't see where this batch references the directory or config.cfg file.  Does it have to be run in same directory is that why?

0
Bill PrewIT / Software Engineering ConsultantCommented:
The file name to process is passed as a command line parm, not hard coded into the script.  See my prior post for example command line.

~bp
0
icecom4Author Commented:
I notice that you put "config.sys" and that does not find anything, but the file name it is config.cfg
so I changed it and it does find.  However I also notice that this does not find config.cfg in all subdirectories and has to be pointed to a specific one.  That will not work as there are many different user folders that may have this file.  But for testing purposes I am ok with pointing directly to file.  

I ran the vbs script with passing command...
All it said was...
"Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved"
It did not add or delete any lines

I ran the batch and it did not report anything and did not edit any lines either





0
icecom4Author Commented:
perhaps to simply this even further, can we make a batch that finds all text files in a directory/subdirectories named "config.cfg"  and simply append the below lines to end of file?

seta com_hunkmegs "192"
seta com_soundmegs "32"
seta com_zonemegs "32"
seta seta cl_punkbuster "1"
seta cl_punkbuster "1"

I am ok with not deleting because any duplicate commands at end of file take priority over the ones before it.  So maybe this will allow for a less complex batch?

0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Very simplistic approach:
@echo off
for /F "tokens=*" %%F in ('dir c:\StartFolder\config.sys /s/b') do (
(echo seta com_hunkmegs "192"
 echo seta com_soundmegs "32"
 echo seta com_zonemegs "32"
 echo seta seta cl_punkbuster "1"
 echo seta cl_punkbuster "1"
) >> "%%F")

Open in new window

It will go for all files config.sys in folder C:\StartFolder and subfolders, and just append those five lines.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ReneGeCommented:
Inspired by Billprew's script, here is another tested approach!

Cheers,
Rene


@ECHO OFF
SETLOCAL EnableDelayedExpansion

REM BASE FOLDER IS WHERE THE BATCH FILE IS LOCATED
SET BaseFolder=%~dp0
SET File=config.cfg

FOR /R "%BaseFolder%" %%A IN (config.cfg) do (
   SET FileSource=%%~fA
   SET FileBackup=%%~dpnA_bak_%random%%random%%%~xA
   SET FileTemp=%%~dpnA_tmp%%~xA
   ECHO [!FileSource!]
   IF EXIST "!FileTemp!" DEL /f /q "!FileTemp!"
   COPY /y "%%~fA" "!FileBackup!"
   
   FOR /F "usebackq tokens=1-4 delims= " %%B IN ("%%A") DO (
      SET Line=%%B %%C %%D
      IF "%%B %%C" == "seta com_hunkmegs" SET line=%%B %%C "192"
      IF "%%B %%C" == "seta com_soundmegs" SET line=%%B %%C "32"
      IF "%%B %%C" == "seta com_zonemegs" SET line=%%B %%C "32"
      IF "%%B %%C" == "seta cl_punkbuster" SET line=%%B %%C "1"
      IF "%%B %%C" == "seta cl_punkbuster" SET line=%%B %%C "1"
      ECHO !Line!>>"!FileTemp!"
   )
   
   COPY /y "!FileTemp!" "!FileSource!" >NUL
   DEL /f /q "!FileTemp!"
)

PAUSE
EXIT

Open in new window

0
icecom4Author Commented:
Thanks guys.  All of these worked to some extent with minor adjustments, Qelmo's worked perfectly.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.