Pythonで巨大テキストファイルを操作・検索する

エラー吐かせまくってまた巨大なログファイルを作ってしまった戒め

なんやかんやあって、数ギガの巨大なテキストファイルができてしまったが、何とか中身を見たい時ってないでしょうか?まあないのが一番なんですが。

そのサイズだと普通のテキストエディタでは開けないので、開かずして情報を得る&開けるようにするためにPythonでいろいろ操作するコード集です。もちろん別にサイズが巨大じゃなくても使えますが、テキストエディタで開けるサイズならテキストエディタで開いた方がいいと思います。
やってることは、ファイル開いてループで回してインデックスで行数取得したり、読み込んだ文字列と任意の文字列を比較したりしてるだけなんですが、だいたいこれが必要になる場面は焦ってるときか、パッとコードが出てこない時なので、コピペで使えるように残しておきます。

ファイルを開くときにwithを使ってたり使ってなかったり、行数、行の内容取得にenumerateを使ってたり使ってなかったりしますがどちらでも問題ないと思います。混じってるのは気分です。多分。

余談ですが、文字コードとか内容とかにはよるものの、テキストファイルは1Gバイトでだいたい1500~2000万行くらいです。特に役に立たない知識でした。

ファイルの行数が知りたい

まずどれくらい大きいのか知るためにファイルの行数を求めます。

Python
with open("ファイルパス", encoding="utf-8") as f:
    for line_count, _ in enumerate(f, 1):
        pass
    print(line_count)

任意の文字列が出現する行数が知りたい

breakを入れてるため一番最初にヒットした行の内容と行数が出力されるコードになってますが、除けてやればヒットする全部の行が得られます。

Python
with open("抜き出し元のパス", encoding="utf-8") as f:
    for line_count, line in enumerate(f, 1):
        if "検索する文字列" in line:
            print(line)
            print(line_count)
            break

ある行以降を別ファイルに出力

上記の「任意の文字列が出現する行数」で取得した行数を基に、ある行から後ろだけ別ファイルに出力します。
時刻を指定して行を求めて、ある時間以降を別ファイルに分けるのに使ったりしました。
何行目以降は出さないなどと条件を追加すればある行数の範囲だけ抜き出したりもできると思います。

Python
out_file = "出力ファイルパス"
output = open(out_file, "w")
with open("抜き出し元のパス", encoding="utf-8") as f:
    line = f.readline()
    line_index = 1
    while line:
        if line_index >= 0: # 出力を開始する行数
        output.write(line)
    line = f.readline()
    line_index += 1
output.close()

任意の行数でファイルを分割する

巨大なファイルを一定行数ごとに分割するプログラム。ファイルサイズを小さくすることでテキストエディタで開けるようにします。
以下では1000000行ごとに別ファイルに書き出します。
分割後のファイル名は連番です。

Python
out_file_name_temp = "分割後のファイルパス_%d.log"
max_lines = 1000000  # 分割する行数
split_index = 1
line_index = 1

out_file = open(out_file_name_temp % (split_index,), "w")
with open("分割元のファイルパス", encoding="utf-8") as f:
    line = f.readline()
    while line:
        if line_index > max_lines:
            out_file.close()
            split_index = split_index + 1
            line_index = 1
            out_file = open(out_file_name_temp % (split_index,), "w")
        out_file.write(line)
        line_index = line_index + 1
        line = f.readline()
out_file.close()

コメント

タイトルとURLをコピーしました