Last active
March 2, 2024 17:00
-
-
Save zzstoatzz/607feb85084c491d3e456af61194b07a to your computer and use it in GitHub Desktop.
find the last n lines of a text file assumed to end with a newline character
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pathlib import Path | |
def reverse_readline(filepath, N): | |
with filepath.open('rb') as f: | |
f.seek(0, 2) | |
filesize = f.tell() | |
lines_found = [] | |
buffer = bytearray() | |
chunk_size = 8192 # Read in chunks of 8KB | |
position = filesize | |
while position >= 0 and len(lines_found) < N: | |
position -= chunk_size | |
if position < 0: | |
chunk_size += position # Adjust chunk_size if it overshoots the start of the file | |
position = 0 | |
f.seek(position) | |
chunk = f.read(chunk_size) + buffer | |
lines = chunk.split(b'\n') | |
# Process all lines found, except potentially incomplete first line in chunk | |
for i in range(len(lines) - 1, 0, -1): | |
lines_found.append(lines[i].decode(errors='ignore')) | |
if len(lines_found) == N: | |
break | |
buffer = lines[0] # Handle any incomplete line by prepending it to the buffer for the next chunk | |
if buffer: | |
# Ensure any remaining buffer (e.g., the first line of the file) is included | |
lines_found.append(buffer.decode(errors='ignore')) | |
return reversed(lines_found) | |
filepath = Path('file.txt') | |
last_n_lines = reverse_readline(filepath, N=5) | |
for line in last_n_lines: | |
print(line) |
Author
zzstoatzz
commented
Mar 2, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment