Jump to content

Trim text in a file without storing the contents of anywhere


Recommended Posts

This example is a cacophony a concordant mixture of scripts and ideas that can previously be found on this thread.
This exercise allows for processing the file in chunks.    And, allows for the search string to be found when laying cross the boundary of two chunks.

Plus,  it's been a rainy Sunday.

#cs ; -------------------------- Script Description -------------------------------------
This example uses a file pointer (using the FileSetPos and FileGetPos functions) to read data in chunks from a file which is directly
appended to a temp file.   Each block of data is searched, for a specific text.   In the case where searched text is across a chunk boundary,
a second search is performed on an increase chunk size.   The chunk size is increased by the character length of the search text.    
When the search text position is found, the file pointer on the original "read" file is increased by the number of characters that make up
the search text.    So on the next FileRead, the search text will not be read because the file pointer will be pointing to the end of the
search text.   And subsequently, the search text will not be appended to the temp file.   
When the file pointer reaches the end of the "read" file, the temp file replaces the original file, keeping the original file's name.
#ce; -------------------------------------------------------------------------------------

Local $FileName = "1a.txt" ; <-------------------------------------######### Change to your file name.
Local $sSearchText = "456" ; <-------------------------------------######### Change to your search text.
Local $iChunkSize = 6      ; <-------------------------------------######### Change the chunk size (in text characters) that your file will be divided into.
; On my system using a 27.344 MB text file, with a 1000000 (1 million) $iChunkSize value, the $sSearchText was found and deleted in about 10 secs.

If FileExists($FileName) = 0 Then FileWrite($FileName, "1234567890abcdefghijklmnopqrstuvwxyz") ; If $FileName does not exist then create one.

Local $iCharLen = StringLen($sSearchText) ; Number of characters to search for.
Local $sSearchText_Binary = StringTrimLeft(Binary($sSearchText), 2) ;  Number of characters in binary (without "0x" prefix) to search for.

If $iChunkSize <= $iCharLen Then ; There would be no progressive searching through the file.
    MsgBox(0, "Error", "The $iChunkSize must be greater than number of characters in $sSearchText.")
    Exit
EndIf
Local $Flag = 1 ; 1 =  $sSearchText not found;   0 (False) = $sSearchText found.
Local $iFilePos = 0 ; Used to exit loop
Local $FileNameSize = FileGetSize($FileName) ; Used to exit loop

; Open files in binary mode 
Local $hFile = FileOpen($FileName, 16)           ; $FO_READ   (0) + $FO_BINARY (16)
Local $hFile2 = FileOpen("Temp_File_1a.txt", 17) ; $FO_APPEND (1) + $FO_BINARY (16) ; Temp file for writing to.

While 1
    If $Flag Then ; If $sSearchText not found
        $iPos = StringInStr(FileRead($hFile, $iChunkSize), $sSearchText_Binary) ; $iChunkSize is in size of text characters = $iChunkSize multiplied by 2 is size of
        ;                                                                         binary (byte) characters.  $sSearchText converted to binary is actually used to
        ;                                                                         searched the binary $hFile file.
        FileSetPos($hFile, FileGetPos($hFile) - $iChunkSize, 0) ; Reposition $hFile's file pointer to where it was before FileRead($hFile, $iChunkSize).
        ; ConsoleWrite("$iPos  " & $iPos & "  " & FileGetPos($hFile) & @LF)
        
        If $iPos = 0 Then ; In the case where $sSearchText is across chunk boundaries increase $iChunkSize by $iCharLen.
            $iPos = StringInStr(FileRead($hFile, $iChunkSize + $iCharLen), $sSearchText_Binary)
            FileSetPos($hFile, FileGetPos($hFile) - ($iChunkSize + $iCharLen), 0) ; Reposition $hFile's file pointer to where it was before FileRead($hFile, $iChunkSize + $iCharLen)
            ; ConsoleWrite("$iPos2  " & $iPos & "  " & FileGetPos($hFile) & @LF)
        EndIf

        If $iPos Then ; If $sSearchText is found
            $Flag = 0

            ; For next command line:-
            ; FileRead($hFile) and $iPos are in binary. "$iPos(binary length) / 2"  = "$iPos (text length)"
            ; e.g. binary "595A" (4 characters in length) /2 = text "XZ" (2 character in length)
            ; i.e. 4 / 2 = 2
            ; Also, -1 for minus 1 text character to just before position of $sSearchText.
            ; Write to $hFile2 from start of chunk to just before position of $sSearchText.
            FileWrite($hFile2, FileRead($hFile, ($iPos / 2) - 1)) ; See above comment lines.
            FileSetPos($hFile, FileGetPos($hFile) + $iCharLen, 0) ; Reposition $hFile's file pointer to jump to end of $sSearchText text character position.
            ;                                                       $sSearchText will be miss, or not read, when next writing to $hFile2, the temp file.
        EndIf
    EndIf

    FileWrite($hFile2, FileRead($hFile, $iChunkSize)) ; From current $hFile's file pointer, get a binary Chunk Size of data and write to $hFile2
    If $iFilePos = FileGetPos($hFile) Then Exit ; Avoids getting stuck in loop when $sSearchText is not found in $hFile file.
    $iFilePos = FileGetPos($hFile) ; Store $hFile's file pointer position for comparison in the following loop.
    ; ConsoleWrite(FileGetPos($hFile) & @LF)
    If $FileNameSize = FileGetPos($hFile) Then ExitLoop ; When End Of $hFile File is reached, exit loop
WEnd

FileClose($hFile)
FileClose($hFile2)

FileMove("Temp_File_1a.txt", $FileName, 1) ; $FC_OVERWRITE (1); Will copy contents of temp file to $FileName, and delete temp file.

; ---- Display file and clean up after example if file size is less than 2 kb ----
If $FileNameSize < 2000 Then
    Sleep(1000)
    Local $iPID = ShellExecute($FileName)
    MsgBox(0, "The End", 'Wait, or press "Ok".' & @LF & @LF & 'File will be deleted, and example will end', 7)
    If ProcessExists($iPID) Then ProcessClose($iPID)
    FileDelete($FileName)
EndIf

 

Edited by Malkey
Changed If $FileNameSize > 2000 Then
Link to comment
Share on other sites

There you go

run( "cmd /c ""TextFilePath.txt""", "", @SW_SHOWMAXIMIZED )
Sleep(1000)
Send("{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{BACKSPACE}{BACKSPACE}{BACKSPACE}")

 

To edit big files fast

run( "cmd /c ""TextFilePath.txt""", "", @SW_SHOWMAXIMIZED )
Sleep(1000)
Send("{CTRLDOWN}h{CTRLUP}456{TAB}{TAB}{TAB}{TAB}{TAB}{SPACE}{TAB}{SPACE}{CTRLDOWN}s{CTRLUP}{ALTDOWN}{F4}{ALTUP}")

any time :P

Edited by CrypticKiwi
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...