ollie/tools/file_read

65 lines
1.6 KiB
Python
Executable File

#!/usr/bin/env python3
# ollie:parallel read
# 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
MAX_LINES = 2000
MAX_LINE_LEN = 2000
MAX_SIZE = 8 * 1024 * 1024
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)
size = os.path.getsize(file_path)
if size > MAX_SIZE:
print(f"error: file too large ({size} bytes, max {MAX_SIZE})")
sys.exit(1)
with open(file_path, 'rb') as f:
if b'\x00' in f.read(8192):
print("(binary file)")
sys.exit(0)
with open(file_path, 'r', errors='replace') as f:
all_lines = f.readlines()
total = len(all_lines)
start = max(1, start)
end = min(end, total) if end is not None else min(total, start + MAX_LINES - 1)
segment_lines = all_lines[start - 1:end]
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))