1

While I was learning how to work with files in Python, I had a question: How can you delete a line from a file that contains a specific word. I wrote the following code:

arr = []
try:
    with open("test.txt") as file:
        arr = file.readlines()
except FileNotFoundError:
    print("File not found!")

word = "five"
try:
    with open("test.txt", "w") as file:
        for row in arr:
            if word not in row:
                file.write(row)
except FileNotFoundError:
    print("File not found!")

But I would like to know if it is possible to do this without writing all the lines in one array, because the file can sometimes be very large and there can be a lack of memory.

Bohdan
  • 13
  • 2
  • 1
    Does this answer your question? [Fastest Way to Delete a Line from Large File in Python](https://stackoverflow.com/questions/2329417/fastest-way-to-delete-a-line-from-large-file-in-python) – Saaru Lindestøkke Feb 08 '23 at 15:46
  • Are your records fixed length by any chance? – JonSG Feb 08 '23 at 15:46
  • the short answer is you can't delete a single line from a file without reading the whole file. You can however read and write in chunks to keep memory usage manageable – el_oso Feb 08 '23 at 15:47
  • 1
    Use, `sed -i '/five/d' test.txt` if ok to not use python – balki Feb 08 '23 at 15:49

3 Answers3

0

You just need to do the following:

  1. open it in read and write mode.
  2. Read it and filter the line out
  3. move the cursor to the begin of the file
  4. write it back
  5. remove anything than is after it
with open("test.txt", "r+") as f: 
    output = filter(lambda line: word not in line, f.readlines()) 
    f.seek(0) 
    f.write(''.join(output)) 
    f.truncate() 

To improve memory usage, just read the file line by line using f.readline() and adjust the seek dinamically.

with open("test.txt", "r+") as f: 
    latest_written_position = f.tell() 
    line = f.readline() 
    reading_position = f.tell() 
    while line: 
        if word not in line: 
            f.seek(latest_written_position) 
            f.write(line) 
            latest_written_position = f.tell() 
            f.seek(reading_position) 
        line = f.readline() 
        reading_position = f.tell() 
    f.seek(latest_written_position) 
    f.truncate() 
Axeltherabbit
  • 680
  • 3
  • 20
-1

This should do the trick:

try:
    with open("test.txt") as file:
        arr = file.readlines()
except IOError:
    from sys import exit as exit_the_progrem
    try:
        exit_the_progrem(__status=-1)
    except:
        import sys
        exiter = sys
        del sys
        exiter.exit()
finally:
    try:
        condtion = True
        arr = ['hello', 'world']  ## or comment?
        locl_i = len(arr)
        for i, elem in enumerate(reversed(arr), start=1):
            locl_i -= i
            if condtion:  # example
                del i
                if not locl_i:
                    del locl_i
                del elem
                del arr[locl_i]
        print(arr)
        with open('out_f.xtxt', 'w') as of:
            of.write(arr)
    except Exception as __this_thing_went_wrong:
        print(__this_thing_went_wrong)
        from sys import exit as exit_the_progrem
        success = 123
        exit_the_progrem(~success)
rv.kvetch
  • 9,940
  • 3
  • 24
  • 53
-2

You can write as you read instead of storing

Consider the following:

try:
    with open("test.txt") as file:
        with open("new_test.txt", "w") as new_file:
            for row in file:
                if word not in row:
                    new_file.write(row)
except FileNotFoundError:
    print("File not found!")
Achille G
  • 748
  • 6
  • 19