はじめに
ログ ファイルの分析には、多くの場合、次の機能が含まれます。最新のエントリを表示します。これは通常、ファイルの最後の n 行を取得する「tail」コマンドを使用して実現されます。この記事では、オフセットをサポートして tail コマンドをエミュレートする Python メソッドの実装について説明します。
Tail の実装
提案された tail() メソッド次のように動作します:
def tail(f, n, offset=0): """Reads a n lines from f with an offset of offset lines.""" avg_line_length = 74 to_read = n + offset while 1: try: f.seek(-(avg_line_length * to_read), 2) except IOError: f.seek(0) pos = f.tell() lines = f.read().splitlines() if len(lines) >= to_read or pos == 0: return lines[-to_read:offset and -offset or None] avg_line_length *= 1.3
このメソッドは平均行長を推定し、パフォーマンスを最適化するために動的に調整します。 .
代替アプローチ
元の実装では、行の長さに関する仮定は、常に当てはまるとは限りません。このような仮定を回避する別のアプローチを次に示します。
def tail(f, lines=20): total_lines_wanted = lines BLOCK_SIZE = 1024 f.seek(0, 2) block_end_byte = f.tell() lines_to_go = total_lines_wanted block_number = -1 blocks = [] while lines_to_go > 0 and block_end_byte > 0: if (block_end_byte - BLOCK_SIZE > 0): f.seek(block_number*BLOCK_SIZE, 2) blocks.append(f.read(BLOCK_SIZE)) else: f.seek(0,0) blocks.append(f.read(block_end_byte)) lines_found = blocks[-1].count('\n') lines_to_go -= lines_found block_end_byte -= BLOCK_SIZE block_number -= 1 all_read_text = ''.join(reversed(blocks)) return '\n'.join(all_read_text.splitlines()[-total_lines_wanted:])
このメソッドは、ファイルを一度に 1 ブロックずつ逆方向に検索し、改行を数えて目的の行を見つけます。
結論
どちらの方法も、オフセット サポートを使用してファイルの最後の n 行を取得するための実行可能なソリューションを提供します。別のアプローチでは、行の長さに関する仮定が回避され、大きなファイルの場合はより効率的になる可能性があります。
以上がPython でファイルの最後の N 行を効率的に取得するにはどうすればよいですか (オフセット サポートあり)?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。