Python Forum

Full Version: Can't seem to figure out how to delete several lines from a text file
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I want to delete a block of text from a text file that looks like this:

Quote:1
Date stored: 2019-02-01;
Author name: l;
Book title: lll;
Quantity: 1;
Price: 2.

2
Date stored: 2019-01-02;
Author name: ghjk;
Book title: okj;
Quantity: 5;
Price: 4.

4
Date stored: 2019-01-02;
Author name: hello;
Book title: hekie;
Quantity: 1;
Price: 2.

1
Date stored: 2019-02-01;
Author name: k;
Book title: k;
Quantity: 4;
Price: 1.

1
Date stored: 2019-01-01;
Author name: o;
Book title: b;
Quantity: 4;
Price: 8.

5
Date stored: 2019-02-01;
Author name: dfgh;
Book title: iuhg;
Quantity: 8;
Price: 4.

But I only want to delete 1 block of text that starts with 1

So I have this code:

from itertools import groupby
    
    mainFileDelete = open("BooksTest.txt","r+")
    
    lst = []
    new = []
    
    for line in mainFileDelete:
        stripped = line.strip("\n")
        lst.append(stripped)
    
    #Makes a list into a list of lists
    def splitList(sequence, delimiter):
        return [list(g) for k, g in groupby(sequence, key = lambda x: x == delimiter) if not k]
    p = splitList(sequence = lst, delimiter = '')
    print(p)
    
    #Gets the sublists that starts with a number '1'
    for k in p:
        this=k
        if this[0] == '1':
            new.append(this)
    print(new)
    
    #Trys to make all of the list of lists into a string an then delete it from 
    #the text file
    for i in new:
        strinng = ''.join(i)
        print(strinng)
        for a in strinng:
            if a != strinng[1]:
                f.write(a)
        f.truncate()
    
    mainFileDelete.close()
It gives me all of the the blocks of text that start with 1 in a list of lists, like so:

[['1', 'Date stored: 2019-02-01; ', 'Author name: l; ', 'Book title: lll; ', 'Quantity: 1; ', 'Price: 2. '], ['1', 'Date stored: 2019-02-01; ', 'Author name: k; ', 'Book title: k; ', 'Quantity: 4; ', 'Price: 1. '], ['1', 'Date stored: 2019-01-01; ', 'Author name: o; ', 'Book title: b; ', 'Quantity: 4; ', 'Price: 8.']]
And I want to delete just the second list from the list of lists. I know how to do it from the actual list. But I don't know how could I also delete it from the file.
I want this one gone from the text file:

Quote:1
Date stored: 2019-02-01;
Author name: k;
Book title: k;
Quantity: 4;
Price: 1.

This is the part from the whole code that should do it:

  #Trys to make all of the list of lists into a string an then delete it from 
        #the text file
        for i in new:
            strinng = ''.join(i)
            print(strinng)
            for a in strinng:
                if a != strinng[1]:
                    f.write(a)
            f.truncate()
But it doesn't work at all. Please help. It's the only thing I can't seem to figure out.
Thank you.
If I look how file is structured - isin't it simpler to drop all rows until first empty row is encountered and do something with remaining rows? Something like:

with open('books_test.txt', 'r') as f:
    for row in f:
        if row in ['\n', '\r\n']:
            break
    for row in f:
        # do something
You seem to be way over complicating this.

with open('BooksTest.txt') as data, open('BooksResult.txt') as output:
    deleted, deleting = False, False
    for line in data:
        if line == '1\n' and not deleted:   # When you find the group, start deleting (not writing) lines.
            deleting = True
        elif deleting:
            if not line.strip():            # When the group is done, mark deletion as done, to only delete once.
                deleting = False
                deleted = True
        else:
            output.write(line)              # Otherwise save (write) the text.
(Dec-10-2019, 02:38 PM)ichabod801 Wrote: [ -> ]You seem to be way over complicating this.

with open('BooksTest.txt') as data, open('BooksResult.txt') as output:
    deleted, deleting = False, False
    for line in data:
        if line == '1\n' and not deleted:   # When you find the group, start deleting (not writing) lines.
            deleting = True
        elif deleting:
            if not line.strip():            # When the group is done, mark deletion as done, to only delete once.
                deleting = False
                deleted = True
        else:
            output.write(line)              # Otherwise save (write) the text.

But my file has several blocks of text that start with 1. And I want the user to be able to select which block of text that starts with 1 they want to delete, not the first block blocks that start with 1.
My code only deletes the first block that starts with 1. Line 5 sets it to delete, but then lines 8 and 9 set it to stop deleting and not delete again. Since 'deleted' is true after line 9, the conditional on line 4 will never be true again, and the rest of the file will be written to output.

If you want to delete the nth block starting with 1, you could modify line 5 to count how many 1's had been found, and to only start deleting if you'd reached the nth one.
(Dec-10-2019, 03:00 PM)ichabod801 Wrote: [ -> ]My code only deletes the first block that starts with 1. Line 5 sets it to delete, but then lines 8 and 9 set it to stop deleting and not delete again. Since 'deleted' is true after line 9, the conditional on line 4 will never be true again, and the rest of the file will be written to output. If you want to delete the nth block starting with 1, you could modify line 5 to count how many 1's had been found, and to only start deleting if you'd reached the nth one.

Should I use find() method? Im seriously lost on this one

I meant count() not find()
Just create a variable called count. Start it at 0. Every time you find a 1, increase count by one (count += 1). When count equals the desired n (for deleting the nth block starting with 1), set deleting = True.

You just need to scan through the file, copying the lines out to another file. When you get to the block you want to delete, stop copying. When you get to the end of that block, start copying again, and mark that you have already deleted, so you won't start deleting again.
with open("BooksTest.txt","r") as data, open("BooksResult.txt","w") as output:
    deleted, deleting = False, False
    count = 0
    for line in data:
        if line == '1\n' and not deleted: # When you find the group, start deleting (not writing) lines.
            count += 1
            if count == 3:
                deleting = True
        elif deleting:
            if not line.strip(): # When the group is done, mark deletion as done, to only delete once.
                deleting = False
                deleted = True
        else:
            output.write(line)
I added the count and everything but when I set count == 3 it also deletes the next block above.
My bad, you need to write the one if you are not deleting:

        if line == '1\n' and not deleted: # When you find the group, start deleting (not writing) lines.
            count += 1
            if count == 3:
                deleting = True
            else:
                output.write(line)
Thank you! It works!