1. ホーム
  2. python

[解決済み] ファイルの最後のn行を取得する、tailと同様の機能

2022-04-13 06:36:40

質問

Webアプリケーションのログファイルビューアを書いているのですが、ログファイルの行をページ分割して表示させたいと思っています。 ファイル内の項目は行単位で、最新の項目が一番下にあります。

そのため tail() を読み取ることができるメソッドです。 n 行を下から順番に表示し、オフセットをサポートします。 これは私が思いついたものです。

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:
            # woops.  apparently file is smaller than what we want
            # to step back, go to the beginning instead
            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, n, offset=None):
    """Reads a n lines from f with an offset of offset lines.  The return
    value is a tuple in the form ``(lines, has_more)`` where `has_more` is
    an indicator that is `True` if there are more lines in the file.
    """
    avg_line_length = 74
    to_read = n + (offset or 0)

    while 1:
        try:
            f.seek(-(avg_line_length * to_read), 2)
        except IOError:
            # woops.  apparently file is smaller than what we want
            # to step back, go to the beginning instead
            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], \
                   len(lines) > to_read or pos > 0
        avg_line_length *= 1.3