Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python truncate lines as they are read

Tags:

python

file-io

I have an application that reads lines from a file and runs its magic on each line as it is read. Once the line is read and properly processed, I would like to delete the line from the file. A backup of the removed line is already being kept. I would like to do something like

file = open('myfile.txt', 'rw+')
for line in file:
   processLine(line)
   file.truncate(line)

This seems like a simple problem, but I would like to do it right rather than a whole lot of complicated seek() and tell() calls.

Maybe all I really want to do is remove a particular line from a file.

After spending far to long on this problem I decided that everyone was probably right and this it just not a good way to do things. It just seemed so elegant solution. What I was looking for was something akin to a FIFO that would just let me pop lines out of a file.

like image 404
Ryan White Avatar asked Feb 08 '09 06:02

Ryan White


People also ask

How do you truncate a line in Python?

Use string slicing to truncate a string Use the syntax string[x:y] to slice a string starting from index x up to but not including the character at index y . If index x is not specified it defaults to zero.

What does truncate () do Python?

Python File truncate() Method The truncate() method resizes the file to the given number of bytes. If the size is not specified, the current position will be used.


2 Answers

Remove all lines after you've done with them:

with open('myfile.txt', 'r+') as file:
    for line in file:
        processLine(line)
    file.truncate(0)

Remove each line independently:

lines = open('myfile.txt').readlines()

for line in lines[::-1]: # process lines in reverse order
    processLine(line)
    del lines[-1]  # remove the [last] line

open('myfile.txt', 'w').writelines(lines)

You can leave only those lines that cause exceptions:

import fileinput

for line in fileinput.input(['myfile.txt'], inplace=1):
    try: processLine(line)
    except Exception:
         sys.stdout.write(line) # it prints to 'myfile.txt'

In general, as other people already said it is a bad idea what you are trying to do.

like image 101
jfs Avatar answered Sep 27 '22 20:09

jfs


You can't. It is just not possible with actual text file implementations on current filesystems.

Text files are sequential, because the lines in a text file can be of any length. Deleting a particular line would mean rewriting the entire file from that point on.

Suppose you have a file with the following 3 lines;

'line1\nline2reallybig\nline3\nlast line'

To delete the second line you'd have to move the third and fourth lines' positions in the disk. The only way would be to store the third and fourth lines somewhere, truncate the file on the second line, and rewrite the missing lines.

If you know the size of every line in the text file, you can truncate the file in any position using .truncate(line_size * line_number) but even then you'd have to rewrite everything after the line.

like image 25
nosklo Avatar answered Sep 27 '22 19:09

nosklo