Find Replace: Difference between revisions

From AutoIt Wiki
Jump to navigation Jump to search
(remove link spam)
(No difference)

Revision as of 03:15, 18 January 2006

Initial post: 21-Jan-2005

Back to Samples

Purpose:

Convert one string to another in a file which is dragged onto the EXE or that is passed by commandline.

Notes:

This solution employs more of a "brute force" approach than one using FileRead("filename", FileGetSize("filename")) .. but has the advantage of being able to handle large files far more efficiently!

Illustrates:

  • Text file processing, including output to a LOG file.
  • Commandline processing.
  • A trick for testing before compile-and-deploy.
  • Elementary usage of a UDF.
  • Hungarian notation and proper indentation.
  • How to get around without "goto".
  • Various methods of AU3 script deployment.
; ----------------------------------------------------------------------------
;
; AutoIt Version: 3.0.103.xxx
; Language:       English
; Author:         Trids 
;
;   SCRIPT FUNCTION:
;   =================
;   an applet to convert a particular string to another in a file
;   which is dragged onto the EXE or that is passed by commandline
;
;   FEATURES
;   =================
;   + Can handle huge files (based on a request from a DBA 
;     to edit her test-scripts of around 200Mb).
;   + Prompts the user for ..
;       o Search String.
;       o Replace String 
;         (defaults with Search String for easy modification).
;       o Output file name 
;         (defaults to Input filename with ".DAT" appendix).
;
;   REQUIREMENTS
;   =================
;   + Commandline parameters
;       o Reference to an input file which has strings to replace.
;   + There may be scope in the future to make adjustments to allow
;     the utility to be run in a scheduled manner <-- in which case,
;     we would replace the current user-prompts with further
;     commandline parameters.
;
;   RESULTS
;   =================
;   - Output file with edits applied.
;   - Errors and other events are reported to a *.LOG file 
;     based on the same name and path as the script.
;
;   DEPLOYMENT
;   =================
;   - Since the applet expects to receive an input file reference from 
;     the commandline, there are several ways to launch the utility.
;       o Drag-and-Drop: just drag the input file onto the icon 
;         of the compiled EXE, or onto a shortcut to the EXE.
;       o SendTo: create a shortcut to the EXE, and place this shortcut in 
;         the "SendTo" folder. This will allow the user to rightclick on 
;         an input file and follow the "Send To" popup menu item to pass 
;         the file to the EXE.
;   
; ----------------------------------------------------------------------------
Global $gsFileLOG = StringTrimRight(@ScriptFullPath,3) & "LOG"

    _WriteLog(@LF & @SCRIPTNAME & " .. starting")
    
; ----------------------------------------------------------------------------
; Confirm that a commandline reference to a valid input file was passed
; ----------------------------------------------------------------------------
    
    $sMsg = ""
    If @COMPILED Then
        ;PROD --> Check for commandline parameter and validate
        ;PROD --> Check for commandline parameter and validate
        ;PROD --> Check for commandline parameter and validate
        If $CmdLine[0] = 0 Then
            $sMsg = "*** ERROR *** No commandline reference was provided, to a TXT file to reformat."
            $sFile_IN = ""
        Else
            $sFile_IN = $CmdLine[1]
        Endif
        If FileExists($sFile_IN) Then
            ;cool
        Else
            $sMsg = "*** ERROR *** The input file to reformat does not exist: """ & $sFile_IN & """"
        Endif
    Else
        ;TEST --> provide default for testing
        ;TEST --> provide default for testing
        ;TEST --> provide default for testing
        $sFile_IN = "P:\bigfile.out"
        MsgBox(4096,"Debug mode", "File to reformat = """ & $sFile_IN & """")
    Endif     

; ----------------------------------------------------------------------------
; Reformat and write
; ----------------------------------------------------------------------------
    While 1     ;<-- dummy loop to avoid goto ;o)
        ;check for error in dragged filename
        If $sMsg <> "" Then 
            _WriteLog($sMsg)
            ExitLoop
        Endif
        
        $sFile_IN = FileGetLongName($sFile_IN)
        
        ;get and check the search string
        $sStr_Find = InputBox(@ScriptName, $sFile_IN & @LF & @LF & ".. FIND this:", "", "", 430, 150)
        If $sStr_Find = "" Then
            _WriteLog("*** ERROR *** Search string must not be empty.")
            ExitLoop
        Else
            _WriteLog("FIND string = """ & $sStr_Find & """")
        Endif
            
        ;get and check the replacement string
        $sStr_Replace = InputBox(@ScriptName, $sFile_IN & @LF & @LF & ".. REPLACE with:", $sStr_Find, "", 430, 150)
        If $sStr_Replace = "" Then
            _WriteLog("*** ERROR *** Replacement string must not be empty.")
            ExitLoop
        Else
            _WriteLog("REPLACE string = """ & $sStr_Replace & """")
        Endif
        
        ;get and check the output file name
        $sFile_OUT = $sFile_IN & ".dat"
        $sFile_OUT = InputBox(@ScriptName, "Output filename", $sFile_OUT, "", 430, 150)
        If $sFile_OUT = "" Then
            _WriteLog("*** ERROR *** Output filename must be specified.")
            ExitLoop
        Else
            _WriteLog("Output file = """ & $sFile_OUT & """")
        Endif
        
        ;apply the edits line by line - faster than manipulating a single string!
        $nFile_IN = FileOpen($sFile_IN,0)
        $nFile_OUT = FileOpen($sFile_OUT,2)
        If $nFile_IN = -1 Or $nFile_OUT = -1 Then 
            _WriteLog("*** ERROR **** problem opening files: (IN/OUT) = (" & $nFile_IN & "/" & $nFile_OUT & ")") 
        Else
            ;process the file
            $nHits = 0
            While 1
                $sData = FileReadLine($nFile_IN)
                If @ERROR = -1 Then ExitLoop
                $sX = StringReplace($sData, $sStr_Find, $sStr_Replace,0,0)
                If @EXTENDED <> 0 Then $nHits = $nHits + 1
                FileWriteLine($nFile_OUT, $sX)
            Wend
            FileClose($nFile_OUT)
            FileClose($nFile_IN)        
            _WriteLog("File created: """ & $sFile_OUT & """")
            _WriteLog("Lines affected: " & $nHits )
            If $nHits Then
                ;nothing to mention
            Else
                MsgBox (4096 + 48, @ScriptName, "No replacements were made!")
                _WriteLog("+++ WARNING +++ No replacements were made!")
            Endif
        Endif
        
        ;Do this all once only
        ExitLoop
    Wend

    _WriteLog(@SCRIPTNAME & " .. ending" & @LF & @LF)


Func _WriteLog($psText)
    FileWriteLine($gsFileLOG , @YEAR & "-" & @MON & "-" & @MDAY & " (" & @HOUR & ":" & @MIN & ":" & @SEC & "): " & $psText)
EndFunc