Jump to content

Deleting specific lines in a text file..


Recommended Posts

I have that same problem at hand, not in a hurry to solve it, but would be nice if i could solve it.

I guess there is one way it could work, that is, FileReadLine the whole file, skipping the lines to be deleted, and copying the ones read to another file, then deleting the original, and renaming the new.

Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Link to comment
Share on other sites

Ok so here we go.

#include <File.au3>

Local $TFile1, $TFile2, $LineToSkip, $LineCount, $Read

$TFile1 = ('File1.txt')
$TFile2 = ('File2.txt')
$LineToSkip = 5

Test()

;=============================================================================

Func Test()
    FileOpen($TFile1, 0)
    FileOpen($TFile2, 2)
    If @error Then
        MsgBox(64, 'Error!', 'There was a problem opening the txt file!')
    Else
    $LineCount = _FileCountLines($TFile1)
    ConsoleWrite($LineCount &' Lines'& @CRLF)
    ProgressOn('Text', 'Working', '', -1, 100, 18)
    For $i = 1 To $LineCount
        $Perc = $i / $LineCount * 100
        ProgressSet($Perc, Round($Perc) & ' % ', 'Working')
        If $i = $LineToSkip Then
            ConsoleWrite('Skipped Line '&$LineToSkip& '!' & @CRLF)
        Else
            $Read = FileReadLine($TFile1, $i)
            If $Read = Not '' Then
                FileWriteLine($TFile2, $Read & @CRLF)
            Else
                TrayTip('Info', 'Done!', 1, 1)
                ExitLoop
            EndIf
        EndIf
    Next
    EndIf
    FileClose($TFile1)
    FileClose($TFile2)
    FileDelete($TFile1)
    FileMove($TFile2, $TFile1, 9)
    Sleep(500)
    ProgressOff()
EndFunc   ;==>Test

;=============================================================================

The objective at the end is to rename from file2 to file1, but somehow that is not working.

Edited by careca
Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Link to comment
Share on other sites

Ok so here we go.

The objective at the end is to rename from file2 to file1, but somehow that is not working.

It is probably using FileOpen yet not using the handles that are returned. If the handle is still open then that can cause an issue such as you describe.

I hope you do not mind for I did a little hack to your code to make it work.

#include <File.au3>

;~ Local $TFile1, $TFile2, $LineToSkip

;~ $TFile1 = ('File1.txt')
;~ $TFile2 = ('File2.txt')
;~ $LineToSkip = 5

Test('File1.txt', 5)
Switch @error
    Case 1, 2
        MsgBox(64, 'Error!', 'There was a problem opening the txt file!')
    Case 3
        MsgBox(64, 'Error!', 'There was a problem reading the whole txt file!')
EndSwitch

;=============================================================================

Func Test($TFile1, $LineToSkip)
    Local $LineCount, $Read, $TFile2
    ; open file for read
    $handle_read = FileOpen($TFile1, 0)
    If $handle_read = -1 Then Return SetError(1, 0, 0)
    ; open file for write
    $TFile2 = _TempFile()
    $handle_write = FileOpen($TFile2, 2)
    If $handle_write = -1 Then
        FileClose($handle_read)
        Return SetError(2, 0, 0)
    EndIf
    ; count lines or read file
    $LineCount = _FileCountLines($TFile1)
    ConsoleWrite($LineCount & ' Lines' & @CRLF)
    ;
    ProgressOn('Text', 'Working', '', -1, 100, 18)
    ;
    For $i = 1 To $LineCount
        $Perc = $i / $LineCount * 100
        ProgressSet($Perc, Round($Perc) & ' % ', 'Working')
        ; read line
        $Read = FileReadLine($handle_read)
        If @error Then ExitLoop
        ;line number to skip else write it 
        If $i = $LineToSkip Then
            ConsoleWrite('Skipped Line ' & $LineToSkip & '!' & @CRLF)
        Else
            FileWriteLine($handle_write, $Read)
        EndIf
    Next
    ; close read and write handles
    FileClose($handle_read)
    FileClose($handle_write)
    ;
    ;FileDelete($TFile1) ; unneeded as next line overwrites
    ; if $i is larger then $LineCount then overwrite the original file
    If $i > $LineCount Then
        FileMove($TFile2, $TFile1, 9)
    Else
        ; else something is incorrect so cleanup and return error
        FileDelete($TFile2)
        Return SetError(3, 0, 0)
    EndIf
    ;
    Sleep(500)
    ProgressOff()
EndFunc   ;==>Test

;=============================================================================

Perhaps you can compare to your code and learn from the differences and create something more to your liking.

Also I noticed that if you look at the remarks for _FileWriteToLine then perhaps it does something similar to this code. That might be worth checking out.

Link to comment
Share on other sites

Hi, thanks, yeah i totally missed the remarks in the help file,

that state clearly that fileopen retrieves a file handle that should then be used to close with fileclose.

After adding that, the script works, i mean it renames correctly, your script has much more error checks, good stuff.

What would be the best way to skip more than one line?

Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Link to comment
Share on other sites

Hi, thanks, yeah i totally missed the remarks in the help file,

that state clearly that fileopen retrieves a file handle that should then be used to close with fileclose.

Excellent.

After adding that, the script works, i mean it renames correctly, your script has much more error checks, good stuff.

What would be the best way to skip more than one line?

Error checks makes the script tell what errored rather then you searching for it. Some time spent on adding error checks by default can save you much time later when something seems bugged. I noticed some subtle bugs like some variables should have made local and ensuring SplashOff on all returns. It needs some refinement.

OK, one more example. Best IMO, is what suits your needs. This a another hack of your code though that I use variable types to make 3 ways to use it. By using Int32, String or Array as a parameter.

  • Use Int32 for a single line. i.e. 5
  • Use String for a | delimited integers in a string. i.e. '3|5'
  • Use Array with integers as elements of the array.
#include <File.au3>

Test('File1.txt', 5) ; INT32 test
;~ Test('File1.txt', '3|5') ; STRING test
Global $array[2] = [3, 5]
;~ Test('File1.txt', $array) ; ARRAY test
Switch @error
    Case 1, 2
        MsgBox(64, 'Error!', 'There was a problem opening the txt file!')
    Case 3
        MsgBox(64, 'Error!', 'There was a problem reading the whole txt file!')
    Case 4
        MsgBox(64, 'Error!', 'Unable to find a valid delimiter in 2nd parameter!')
    Case 5
        MsgBox(64, 'Error!', 'Invalid type passed as 2nd parameter!')
EndSwitch

;=============================================================================

Func Test($TFile1, $LineToSkip)
    Local $handle_read, $handle_write, $i, $item, $LineCount, $Perc, $Read, $TFile2
    ConsoleWrite('$LineToSkip is of type: ' & VarGetType($LineToSkip) & @CRLF)
    ; open file for read
    $handle_read = FileOpen($TFile1, 0)
    If $handle_read = -1 Then Return SetError(1, 0, 0)
    ; open file for write
    $TFile2 = _TempFile()
    $handle_write = FileOpen($TFile2, 2)
    If $handle_write = -1 Then
        FileClose($handle_read)
        Return SetError(2, 0, 0)
    EndIf
    ; count lines and read file
    $LineCount = _FileCountLines($TFile1)
    ConsoleWrite($LineCount & ' Lines' & @CRLF)
    ;
    ProgressOn('Text', 'Working', '', -1, 100, 18)
    ;
    For $i = 1 To $LineCount
        $Perc = $i / $LineCount * 100
        ProgressSet($Perc, Round($Perc) & ' % ', 'Working')
        ; read line
        $Read = FileReadLine($handle_read)
        If @error Then ExitLoop
        ;line number to skip else write it
        Switch VarGetType($LineToSkip)
            Case 'INT32'
                If $i = $LineToSkip Then
                    ConsoleWrite('Skipped Line ' & $LineToSkip & '!' & @CRLF)
                Else
                    FileWriteLine($handle_write, $Read)
                EndIf
            Case 'STRING'
                If StringInStr($LineToSkip, '|') Then
                    ; create an array
                    $LineToSkip = StringSplit($LineToSkip, '|', 2); no return count
                    ContinueCase
                Else
                    ; close read and write handles. set error
                    FileClose($handle_read)
                    FileClose($handle_write)
                    ProgressOff()
                    Return SetError(4, 0, 0)
                EndIf
            Case 'ARRAY'
                For $item In $LineToSkip
                    If $i = $item Then
                        ConsoleWrite('Skipped Line ' & $item & '!' & @CRLF)
                        ContinueLoop 2
                    EndIf
                Next
                FileWriteLine($handle_write, $Read)
            Case Else
                ; close read and write handles. set error
                FileClose($handle_read)
                FileClose($handle_write)
                ProgressOff()
                Return SetError(5, 0, 0)
        EndSwitch
    Next
    ; close read and write handles
    FileClose($handle_read)
    FileClose($handle_write)
    ;
    ; if $i is larger then $LineCount then overwrite the original file
    If $i > $LineCount Then
        FileMove($TFile2, $TFile1, 9)
    Else
        ; else something is incorrect so cleanup and return error
        FileDelete($TFile2)
        ProgressOff()
        Return SetError(3, 0, 0)
    EndIf
    ;
    Sleep(500)
    ProgressOff()
EndFunc   ;==>Test

;=============================================================================

Only use 1 Test() call at a time to test. I cannot see any subtle bugs so perhaps I did better with hacking this one.

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...