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!!
Who is Participating?
QlemoBatchelor, 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.
QlemoBatchelor, 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?
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"
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.

QlemoBatchelor, 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.
Only if all 5 lines are found, "replace" them.
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.  
icecom4Author Commented:
and this is each line...not only if all 5 are found
Bill PrewCommented:
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"


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)
  WScript.Echo "No filename specified."
End If
If (WScript.Arguments.Count > 1) Then
  sOutfile = WScript.Arguments(1)
  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)
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"""

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

' Cleanup and end
Set oFSO = Nothing

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.

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
Bill PrewCommented:
==> 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?


Bill PrewCommented:
Are there any blank lines in the file?

Bill PrewCommented:
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!

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

Open in new window

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?

Bill PrewCommented:
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.

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

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?

Inspired by Billprew's script, here is another tested approach!


SETLOCAL EnableDelayedExpansion

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!"


Open in new window

icecom4Author Commented:
Thanks guys.  All of these worked to some extent with minor adjustments, Qelmo's worked perfectly.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.