ollie/tools/file_read

63 lines
1.5 KiB
Python
Executable File

#!/usr/bin/env python3
# ollie:parallel read
# ollie:tier cold
# description: Read a file with accurate line numbers. Prefer segments (start/end) over full-file reads.
# Args: <file_path> [start] [end]
import sys
import os
from itertools import islice
MAX_LINES = 2000
MAX_LINE_LEN = 2000
if len(sys.argv) < 2:
print("usage: file_read <file_path> [start] [end]")
sys.exit(1)
file_path = sys.argv[1]
start = int(sys.argv[2]) if len(sys.argv) > 2 else 1
end = int(sys.argv[3]) if len(sys.argv) > 3 else None
if not os.path.isabs(file_path):
print(f"error: path must be absolute, got: {file_path}")
sys.exit(1)
if not os.path.exists(file_path):
print("(new file)")
sys.exit(0)
if not os.path.isfile(file_path):
print(f"error: not a regular file: {file_path}")
sys.exit(1)
with open(file_path, 'rb') as f:
if b'\x00' in f.read(8192):
print("(binary file)")
sys.exit(0)
start = max(1, start)
if end is None:
end = start + MAX_LINES - 1
with open(file_path, 'r', errors='replace') as f:
# Skip lines before start
for _ in islice(f, start - 1):
pass
# Read only the lines we need
segment_lines = list(islice(f, end - start + 1))
if not segment_lines:
print("(empty file)" if start == 1 else "(no lines in range)")
sys.exit(0)
out = []
for i, line in enumerate(segment_lines):
lineno = start + i
text = line.rstrip('\n')
if len(text) > MAX_LINE_LEN:
text = text[:MAX_LINE_LEN] + '...'
out.append(f"{lineno:>6}\t{text}")
print('\n'.join(out))