Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Writing to a specific line in a text file (.cfg)

Status
Not open for further replies.

redlair

Technical User
Jun 29, 2004
54
0
0
US

Writing to a specific line in a text file (.cfg)

I manage several Netgear WAP's at several remote locations. I use MAC filtering, which can be difficault to add device MACs to several sites. I usually make a backup.cfg file then add the lines, under the access control table, needed to add a MAC and name to the table. Then restore the backup. I would like to have a script the would prompt a local user for the Device Name and MAC address then search the .cfg file for the Access Control Table and add the line with the new MAC and Name. I have looked over the filesystem object and the text stream method and have not found away to search the .cfg file for a specific section or line then add a line to that section. I guess the hardest part is finding the section then pointing to the correct location the write the line.

SAMPLE NETGEAR.CFG

[528000:Static Routes]
[528001:Static Routing Table]: {
}


[530000:Wireless Configuration]
[530001:SSID]: hammon
[530002:Channel]: 10
[530003:Access Control]: on
[530004:Bridge Enable]: on
[530016:Security Type]: WEP
#usage: None|WEP|WPA_PSK|WPA_8021X
[530005:Access Control Table]: {
[530005_e]: 1) "00-90-96-G6-0d-32" "Laptop 5-57"
[530005_e]: 2) "00-90-96-H6-0d-1e" "Laptop 1-53"
[530005_e]: 3) "00-90-96-J6-99-76" "Laptop 4-56"
[530005_e]: 4) "00-0c-f1-J6-f8-5c" "Laptop 2-54"
[530005_e]: 5) "00-0c-f1-K6-df-63" "Laptop 7-59"
[530005_e]: 6) "00-0c-f1-L7-5e-32" "Laptop 9-61"
[530005_e]: 7) "00-0c-f1-D3-53-4c" "Laptop 6-58"
[530005_e]: 8) "00-0c-f1-F2-56-17" "laptop 8-60"
}
[530006:Authentication Type]: Shared Key
[530007:SSID Broadcast Enable]: on
[530008:Region]: United States
[530009:WEP Key1]: 1e770e0eY6
[530010:WEP Key2]: 1e770e0eY6
[530011:WEP Key3]: 1e770e0eY6
[530012:WEP Key4]: 1e770e0eY6
[530013:Encryption Strength]: 64bit
[530014:Default Key]: 0
[530015:Key length]: 5
[560000:WPA Configuration]
[560001:pre-shared Key]:
[560002:Key Lifetime]: 5
[560003:primary Radius Server]:
[560004:Secondary Radius Server]:
[560005:Radius Port]: 1812
[560006:8021X Shared Key]:
[560007:Radius Accounting]: disabled
[560008:Radius Accounting port]: 1813
[560009:Update Report Interval]: 5
 
Take a look at the InStr function.

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
redlair:

Text file manipulation in any language (VBS included) generally means reading the whole file in, making changes, and writing the whole file back out. There isn't really a way to insert or overwrite data in a file with lines of varying length.

What you will need to do is load the file into memory, do a search to find the location, insert or overwrite with new data, and rewrite the entire file.

In practice it's not too hard and not at all slow for a small text file like what you've shown.

> I would like to have a script the would prompt a local
> user for the Device Name and MAC address then search
> the .cfg file for the Access Control Table and add the
> line with the new MAC and Name.

I assume you would be adding a line after "[530005_e]: 8) "00-0c-f1-F2-56-17" "laptop 8-60"" and before the closing brace on the next line. Something like the following should do the text manipulation part:

Code:
'- AddMACLine2.vbs

Option Explicit

dim fso, aLines, f
dim sFile, sFile2
dim nPos, sLine
dim sMACAddress, sDeviceName

sFile  = "netgear.cfg"
sFile2 = "netgear2.cfg" 'i send output to different file for testing

'- load file into string
set fso = CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile(sFile, 1) 'i 1 = ForReading
sFile = f.ReadAll
f.Close


'- search for "Access Control" then closing brace
nPos = InStr(sFile, "Access Control")
nPos = InStr(nPos + 1, sFile, "}")

'i nPos is now on the actual brace, after the leading whitespace on that line

'~ pretend to get data from user
'~ sMACAddress = InputBox("Enter MAC Address", "AddMACLine", sMACAddress)
'~ sDeviceName = InputBox("Enter Device Name", "AddMACLine", sDeviceName)

sMACAddress = chr(34) & "00-0c-f1-F2-56-18" & chr(34) 'i wrap in double-quotes
sDeviceName = chr(34) & "Laptop 8-61" & chr(34)      


'- build new line to start at brace position, and add leading whitespace on
'  next line (considering indentation is necessary or even just preferred)

sLine = "[530005_e]: 9) " & sMACAddress & "    " & sDeviceName & vbCrLf & _
  "        "

'- insert new line into file text
sFile = left(sFile, nPos - 1) & sLine & mid(sFile, nPos)


'- rewrite file
set f = fso.CreateTextFile(sFile2, true) '- true = overwrite
f.Write sFile
f.Close

set f = nothing
set fso = nothing

'- eof


Another method of reading in file data for manipulation is to load it into an array. Then you need to scan each line individually, but you can also access lines non-sequentially a little more easily:

Code:
'- load file, split into array
set fso = CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile(sFile, 1) 'i 1 = ForReading
[b]aLines = Split(f.ReadAll, vbCrLf)[/b]
f.Close

nLine  = 0
nLines = UBound(aLines)+1

'- find "Access Control" line with sequential search
bFound = false
do while nLine < nLines and not bFound
  sLine = aLines(nLine)
  if InStr(sLine, "Access Control") then
    bFound = true
  else
    nLine = nLine + 1
  end if
loop

'i then search again for "}" from that point

'... manipulate
'- "insert" a line by appending to the array element
aLines(4) = aLines(4) & vbCrLf & "another line"

'- then write it out like this:
[b]f.Write Join(aLines, vbCrLf)[/b]

Hope that's useful.

-xift
 
It is possible through script to grab the MAC address and machine name.

A slight enhancement for you to consider:

Code:
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkAdapter",,48)
For Each objItem in colItems
	If objItem.NetConnectionStatus="2" Then
 		Wscript.Echo "MACAddress: " & objItem.MACAddress
    	Wscript.Echo "SystemName: " & objItem.SystemName
    End If
Next

I hope you find this post helpful. Please let me know if it was.

Regards,

Mark
 
Xift, Thank you. This gives me a great start. I did notice another issue I will have with this script. How can I get the script to change/increment the table number for each line added? For example: [530005_e]: 8), [530005_e]: 9),[530005_e]: 10) ect. Is this even possible? It would have to be able to recognize the last record and then increment the value?



 
markdmac, Thank You I have added this to the script. This will help the user to easily determine the MAC.
 
redlair:

To get the table number from the last record, I think this is where you'll want to use the method that loads the file into an array.

You do the first sequential search to find the "Access Control" line, then again to find the next close brace line.

At this point, nLine-1 will point to the last record, so you could do something like this:

Code:
  nLine = nLine-1 'i point to the last record
  sLine = aLines(nLine) 

  ':          [530005_e]: 8) "00-0c-f1-F2-56-17"    "laptop 8-60"

  nColon = InStr(sLine, ":")
  nParen = InStr(nColon, sLine, ")")

  nRecord = Trim(Mid(sLine, nColon+1, nParen-nColon-1))
  nRecord = nRecord + 1 'i converts string to number

  sLine = Left(sLine, nColon) & " " & nRecord & ") " & "etc"
  'i build rest of line as described before

Here's the full script to do it with arrays, cutting edge sequential searches, and updating the record number:

Code:
'- AddMACLine.vbs
'- 2005-04-05  extract record number from previous line

Option Explicit

dim fso, aLines, f
dim sFile, sFile2
dim nLine, nLines, bFound, sLine
dim sMACAddress, sDeviceName
dim nColon, nParen, nRecord

sFile  = "netgear.cfg"
sFile2 = "netgear4.cfg"

'- load file, split into array
set fso = CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile(sFile, 1) 'i 1 = ForReading
aLines = Split(f.ReadAll, vbCrLf)
f.Close

nLine  = 0
nLines = UBound(aLines)+1

'- find section: "Access Control" line
bFound = false
do while nLine < nLines and not bFound
  sLine = aLines(nLine)
  if InStr(sLine, "Access Control") then
    bFound = true
  else
    nLine = nLine + 1
  end if
loop

'- find last entry: next brace "}"
bFound = false
do while nLine < nLines and not bFound
  sLine = aLines(nLine)
  if InStr(sLine, "}") then
    bFound = true
  else
    nLine = nLine + 1
  end if
loop

'- build new line to insert

'~ sMACAddress = InputBox("Enter MAC Address", "AddMACLine", sMACAddress)
'~ sDeviceName = InputBox("Enter Device Name", "AddMACLine", sDeviceName)

sMACAddress = chr(34) & "00-0c-f1-F2-56-18" & chr(34) 'i pretend entered by user
sDeviceName = chr(34) & "Laptop 8-61" & chr(34)       'i wrap in double-quotes

nLine = nLine - 1 'i back up to the last record
sLine = aLines(nLine) 

':          [530005_e]: 8) "00-0c-f1-F2-56-17"    "laptop 8-60"

nColon = InStr(sLine, ":")
nParen = InStr(nColon, sLine, ")")

nRecord = Trim(Mid(sLine, nColon+1, nParen-nColon-1))
nRecord = nRecord + 1 'i converts string to number and advances

sLine = Left(sLine, nColon) & " " & nRecord & ") " & sMACAddress & _
  "    " & sDeviceName

'i build line starting with original line up to and including colon, then
'  add the new record number, and then add the user-entered values

'i then add the new line to the end of the last record
aLines(nLine) = aLines(nLine) & vbCrLf & sLine


'- rewrite file
set f = fso.CreateTextFile(sFile2, true) '- true = overwrite
f.Write Join(aLines, vbCrLf)
f.Close

set f = nothing
set fso = nothing

'- eof

Just in case you or anyone was wondering about my silly commenting scheme, the character after the single-quote tells what kind of comment it is:
Code:
  -  major program step, pseudo-code
  ~  code to be implemented
  :  the format or contents of something
  i  informational or explanatory comment for the reader

Ones I didn't use here but use frequently in my own code:
Code:
  x  code to be deleted once replacement is tested
  z  code that is put to sleep, disabled but not to be deleted ("commented
     out")
  !  problem code: should be reworked or fixed in some way
  >  code to be encapsulated in a function, or a function to
     be moved to another file

I find it enormously useful to do this, especially looking back at code I wrote several years ago. Comments are used for a number of different jobs, and I think it helps to identify that. It helps me remember what was going on with a piece of code if I describe the intent of each comment. Further, I can search a source file for "'!" to find any problems or "todo" items I've identified, or search for "'x" to find things to remove, and so on.

Anyway, hope the code helps and hope the comments about comments are at least amusing or even useful.

- xift
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top