Announcement

Collapse
No announcement yet.

multiple item search & insert next line?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • multiple item search & insert next line?

    Hello,
    This problem seems to lend it self to scripting. can usually find parts of other examples and workout the syntax, when I have figured out what to do.

    background and problem description:
    have a group of files, approximately 300. that need to be updated.
    each compiled file has a text file embedded in it. will pre-process each to extract the text file.
    Each text file to be searched for multiple items. two lines should be inserted after each match. a counter should be kept to indicate the total number of items found. then each file will have a block of several lines of text appended to the end of the file. with the value of the counter included in the block.

    description of the steps:
    preprocess each file to export the text. (ent file)
    this involves calling an external program to process each file. no problems here.

    define a set of items ("item1", "item2", "item3")
    stuff1 is two lines of text to be inserted.
    stuff2 is a group of lines to be appended to the end of the file.

    open a text file.
    search for an item in the set.
    when a match is found
    increment the counter, insert two lines. (stuff1)
    search for the next item.

    if any items are found append stuff2 to the end of file.
    stuff2 includes the value of the counter.

    [manual verification of links in updated text files]
    postprocess to import the updated ent file. no problem.

    now the question: where to start?
    here is what I have used for search and replace text in other files. not sure how to insert a line of text after finding a match. Or the second part about appending text to the end of the file. maybe close the file and reopen for append?

    Code:
    Dim f, fc, afile
    Const ForReading = 1
    Const ForWriting = 2
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    Set f = objfso.GetFolder(".")
    Set fc = f.Files
    
    For Each aFile In fc
      'If UCase(Right(aFile.Name, 3)) = "CFG" then
      If Left(afile.Type, 3) = "CFG" Then
    
    Set objFile = objFSO.OpenTextFile(afile, ForReading)
    strText = objFile.ReadAll
    objFile.Close
    strNewText = Replace(strText, "mp_multiplespawn 0", "mp_multiplespawn 1")
    
    Set objFile = objFSO.OpenTextFile(afile, ForWriting)
    objFile.WriteLine strNewText
    objFile.Close
    
      End If
    Next
    if anyone can help me get started, thanks.

  • #2
    Re: multiple item search & insert next line?

    I 'm not sure what exactly you are looking for, but here are some ideas.
    Maybe it can help you getting started.

    Code:
    'all the variables needed
    strFolder = "c:\scripts"
    strFileExtension = "txt"
    
    strSearchString = "mp_multiplespawn 0"
    strReplaceString = "mp_multiplespawn 1"
    
    stuff1 = "*** insert this Line first" & vbNewLine _
           & "*** then insert this second line"
    
    stuff2 = "*** line1 blabla" & vbNewLine _
           & "*** blabla Line2" & vbNewLine _
           & "*** result: %LineCount% line(s) counted containing the searchstring" & vbNewLine _
           & "*** last line"
    
    'begin the main script
    Const ForReading = 1, ForWriting = 2, ForAppending = 8
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    Set  f = objfso.GetFolder(strFolder)
    Set fc = f.Files
    
    For Each aFile In fc
    
      If LCase(objFSO.GetExtensionName(aFile.name)) _
                     = LCase(strFileExtension) then
        LineCnt = vbEmpty
        Set objFile = objFSO.OpenTextFile(afile.path, ForReading, True, 0)
    
        Do Until objFile.AtEndOfStream
          strLine = objFile.ReadLine
    
          If CBool(InStr(strLine,strSearchString)) Then
            LineCnt = LineCnt + 1
            tmpContent = tmpContent _
                       & Replace(strLine, strSearchString, strReplaceString) _
                       & vbNewLine & stuff1 & vbNewLine
          Else
            tmpContent = tmpContent & strLine & vbNewLine
          End If
        Loop
        objFile.Close
    
        If LineCnt > 0 Then
         Set objFile = objFSO.OpenTextFile(afile.path, ForWriting, true, 0)
         tmpContent = tmpContent _
                    & Replace(stuff2, "%LineCount%", LineCnt)
         objFile.WriteLine tmpContent
         objFile.Close
        End If
    
      End If
      
    Next 'go to the next file
    
    msgbox "done all"
    It is not possible to insert lines in an existing file. What this script does is reading the existing file line-by-line.
    Then it wil join the lines again by appending each lines to a string called tmpContent. But before a line will be added to tmpContent, it is possible to change text on that line and enhance it with extra lines.
    After the last line of the file is read, the script then checks if there where changes made, it uses the LineCnt (=number of lines where the 'searchstring' was found) for that. If there where changes the original file will be overwritten by the tmpContent.

    \Rems

    This posting is provided "AS IS" with no warranties, and confers no rights.

    __________________

    ** Remember to give credit where credit's due **
    and leave Reputation Points for meaningful posts

    Comment


    • #3
      Re: multiple item search & insert next line?

      it is better that you show an example input file format and an example of how the resulting file contents should look like after replacement.

      Comment


      • #4
        Re: multiple item search & insert next line?

        Originally posted by Rems View Post
        ..

        It is not possible to insert lines in an existing file. What this script does is reading the existing file line-by-line.
        Then it wil join the lines again by appending each lines to a string called tmpContent. But before a line will be added to tmpContent, it is possible to change text on that line and enhance it with extra lines.
        After the last line of the file is read, the script then checks if there where changes made, it uses the LineCnt (=number of lines where the 'searchstring' was found) for that. If there where changes the original file will be overwritten by the tmpContent.

        \Rems
        another way is to just print out the line that is going to be inserted when the pattern is found:
        Code:
        for each line 
            if pattern in line: 
                print line 
                print insertlinehere
            else
                print line

        Comment


        • #5
          Re: multiple item search & insert next line?

          hello all,
          thanks for your reply.
          here is what I have now:
          kind of a hack. it is a little hard to add new items to search for. could not figure out how to make it cleaner.
          would post the text file before and after. but it is 3400 lines.

          Code:
          Dim f, fc, afile, strText, strLine
          Const ForReading = 1
          Const ForWriting = 2
          Dim objFSO2: Set objFSO2 = CreateObject("Scripting.FileSystemObject")
          
          Set objFSO = CreateObject("Scripting.FileSystemObject")
          
          Set f = objfso.GetFolder(".")
          Set fc = f.Files
          
          For Each aFile In fc
            'If UCase(Right(aFile.Name, 3)) = "ENT" then
            If Left(afile.Type, 3) = "ENT" Then
          
          Set objFile = objFSO.OpenTextFile(afile, ForReading)
          strText = objFile.ReadAll
          objFile.Close
          
          Dim colmatches
          'alien_slave counter
          With New RegExp
          .IgnoreCase = True
          .Global = True
          .Pattern = "monster_alien_slave" 
          Set colMatches = .Execute(strText)
          ialien_slavescount = colmatches.count
          End With
          
          'barnacle counter
          With New RegExp
          .IgnoreCase = True
          .Global = True
          .Pattern = "monster_barnacle" 
          Set colMatches = .Execute(strText)
          ibarnaclecount = colmatches.count
          End With
          
          'headcrab counter
          With New RegExp
          .IgnoreCase = True
          .Global = True
          .Pattern = "monster_headcrab" 
          Set colMatches = .Execute(strText)
          iheadcrabcount = colmatches.count
          End With
          
          'houndeye counter
          With New RegExp
          .IgnoreCase = True
          .Global = True
          .Pattern = "monster_houndeye" 
          Set colMatches = .Execute(strText)
          ihoundeyecount = colmatches.count
          End With
          
          'zombie counter
          'Dim colmatches
          With New RegExp
          .IgnoreCase = True
          .Global = True
          .Pattern = "monster_zombie" 
          Set colMatches = .Execute(strText)
          izombiecount = colmatches.count
          End With
          
          'sum the counters
          icount = ialien_slavecount + ibarnaclecount + iheadcrabcount + ihoundeyecount + izombiecount
          
          'insert headcrab stuff
          strstuff = Chr(34) & "monster_headcrab" &Chr(34)
          strNewText = Replace(strText, _
          strstuff, _
          strstuff _
          &vbNewLine &Chr(34) &"TriggerTarget" &Chr(34) & " " &chr(34) &"MonsterCounter" &Chr(34) _
          &vbNewLine &Chr(34) & "TriggerCondition" &Chr(34) & " " &chr(34) & "4" &Chr(34))
          If iheadcrabcount > 0 Then
          strText = strNewText
          End If
          
          'insert houndeye stuff
          strstuff = Chr(34) & "monster_houndeye" &Chr(34)
          strNewText = Replace(strText, _
          strstuff, _
          strstuff _
          &vbNewLine &Chr(34) &"TriggerTarget" &Chr(34) & " " &chr(34) &"MonsterCounter" &Chr(34) _
          &vbNewLine &Chr(34) & "TriggerCondition" &Chr(34) & " " &chr(34) & "4" &Chr(34))
          If ihoundeyecount > 0 Then
          strText = strNewText
          End If
          
          'insert zombie stuff 
          strstuff = Chr(34) & "monster_zombie" &Chr(34)
          strNewText = Replace(strText, _
          strstuff, _
          strstuff _
          &vbNewLine &Chr(34) &"TriggerTarget" &Chr(34) & " " &chr(34) &"MonsterCounter" &Chr(34) _
          &vbNewLine &Chr(34) & "TriggerCondition" &Chr(34) & " " &chr(34) & "4" &Chr(34))
          If izombiecount > 0 Then
          strText = strNewText
          End If
          
          'get the name of the nextmap from the mapname.cfg file.
          'search for nextmap capture the rest of the line.
          arrfilename = Split(afile.Name,".")
          strbasename = arrfilename(0)
          'WScript.Echo (strbasename)
          strInput = strbasename & ".cfg"
          'WScript.Echo (strOutput)
          If objFSO2.FileExists(strInput) Then 
          Set objFile2 = objFSO2.OpenTextFile(strInput, ForReading)
          strText2 = objFile2.ReadAll
          'If strtext2 = "" Then WScript.Echo("what the fuck") End if
          strnextmap = GetNextMap(strtext2)
          
          objFile2.Close
                     If strnextmap <> "" Then
                   'wscript.echo "Search For 'map' in: " & strOutput _
                   '& vbcrlf & "Result: " & strnextmap & vbCRLF
                        strnextmap = Replace(strnextmap, "nextmap", "")
                        strnextmap = Replace(strnextmap, """", "")
                        strnextmap = replace(strnextmap,vbcr,"")
                       strNextmap2 = Trim(strnextmap)
          'If strnextmap2 = "c1a0d" Then WScript.Echo ("***" &strnextmap2 &"***") End if
           End if
          End If
          
          'strnextmap2 = "c1a0d"
          'find the line: "map" "nameofnextmap" in the ent file.
          'replace it with it plus newline and more stuff. insert two lines.
          strmorestuff = Chr(34) &strnextmap2 &Chr(34)
          'WScript.Echo (strmorestuff)
          strNewText = Replace(strText, strmorestuff, _
          strmorestuff &vbNewLine &Chr(34) &"targetname" &Chr(34) &" " &Chr(34) &"killall" &Chr(34)_
          &vbNewLine &Chr(34) &"spawnflags" &Chr(34) &" " &Chr(34) &"3" &Chr(34))
          
          
          Set objFile = objFSO.OpenTextFile(afile, ForWriting)
          'purge odd little squares.
          strNewText = replace(strNewText, chr(00), "")
          strnewtext = trim(replace(strnewtext,chr(20)&chr(20),""))
          strnewtext = Trim(replace(Replace(Replace(strnewtext, vbcr, ""), vblf, vbcrlf), vbcrlf&vbcrlf,""))
          objFile.WriteLine strNewText
          
          'append other stuff
          objFile.WriteLine "{"
          objFile.WriteLine chr(34) &"target" &Chr(34) &" " &chr(34) &"EndMapRelay" &Chr(34)
          objFile.WriteLine Chr(34) &"targetname" &Chr(34) &" " &Chr(34) &"MonsterCounter" &Chr(34)
          objFile.WriteLine Chr(34) &"count"&Chr(34) &" " &Chr(34) &iCount-2 &Chr(34)
          objFile.WriteLine Chr(34) &"classname" &Chr(34) &" " &Chr(34) &"trigger_counter" &Chr(34)
          objFile.WriteLine "}"
          'save till I find orig ch level
          'objFile.WriteLine Chr(34) &"targetname" &Chr(34) &" " &Chr(34) &"killall" &Chr(34)
          'objFile.WriteLine Chr(34) &"spawnflags" &Chr(34) &" " &Chr(34) &"3" &Chr(34)
          objFile.WriteLine "{"
          objFile.WriteLine Chr(34) &"targetname" &Chr(34) &" " &Chr(34) &"EndMapRelay" &Chr(34)
          objFile.WriteLine chr(34) &"target" &Chr(34) &" " &chr(34) &"killall" &Chr(34)
          objFile.WriteLine Chr(34) &"triggerstate" &Chr(34) & " " &Chr(34) &"1" &Chr(34)
          objFile.WriteLine Chr(34) &"classname" &Chr(34) &" " &Chr(34) &"trigger_relay" &Chr(34)
          objFile.WriteLine "}"
          objFile.Close
            End If
          Next
          
          Function GetNextMap(strText2)
            Dim oRE
            Dim colMatches
            Dim oMatch, I
          
            Set oRE = New Regexp
            oRE.Global = True
            oRE.Pattern = "nextmap(.*)"
            oRE.IgnoreCase = True
            Set colMatches = oRE.Execute(strText2)
          
            For Each oMatch In colMatches
              GetNextMap = GetNextMap & oMatch.Value
            Next
          
          End Function
          summary: searches for matching items and creates a count of each item. then does a search and replace: searches through a text file. finds a match then replaces the item. with the item plus a newline. and the two lines are inserted then.

          searches a sister text file for a key item name. then searches for that key in the original text file. and inserts more stuff there.

          there are some odd little squares(control characters at the end of the file which cause problems when text is inserted after them. cleanup the text file remove little squares, delete blank lines, and convert single carriage returns into crlf pairs.

          then append about 10 lines at the end of the text file.

          need to add several new search items. but it is such a mess now it is hard to work with.

          Comment


          • #6
            Re: multiple item search &amp; insert next line?

            here is a sample partial before and after:

            "monstertype" "monster_headcrab"
            becomes
            "monstertype" "monster_headcrab"
            "TriggerTarget" "MonsterCounter"
            "TriggerCondition" "4"

            "monstertype" "monster_zombie"
            becomes
            "monstertype" "monster_zombie"
            "TriggerTarget" "MonsterCounter"
            "TriggerCondition" "4"

            this continues for all types of monsters...

            "map" "c1a1a"
            becomes
            "map" "c1a1a"
            "targetname" "alldead_cl"
            "spawnflags" "3"
            c1a1a is the variable key item obtained from another file.
            by searching for "nextmap" "??????"
            what a mess when it does not exist in the other file!

            this:
            {
            "model" "*4"
            "landmark" "c1a1"
            "map" "c1a1a"
            "classname" "trigger_changelevel"
            }
            becomes:
            {
            "model" "*4"
            "landmark" "c1a1"
            "map" "c1a1a"
            "targetname" "alldead_cl"
            "spawnflags" "3"
            "classname" "trigger_changelevel"
            }

            lines appended at the end of the file.
            {
            "target" "EndMapRelay"
            "targetname" "MonsterCounter"
            "count" "1"
            "classname" "trigger_counter"
            }
            {
            "targetname" "EndMapRelay"
            "target" "alldead_cl"
            "triggerstate" "1"
            "classname" "trigger_relay"
            }

            Comment

            Working...
            X