sedで大きなファイルを処理すると遅い/メモリエラーになる場合

  • URLをコピーしました!

sedはログ解析やテキスト整形に便利なツールですが、数百MB〜数GBクラスの大きなファイルを処理すると、急に遅くなったり、メモリエラーが発生することがあります。

この記事では、なぜそのような現象が起きるのか、そして実用的な対処方法を解説します。

目次

1. なぜsedが遅くなるのか?

(1) sedの仕組み

sedは「1行をパターンスペースに読み込み → 処理 → 出力」を繰り返す仕組みです。
そのため、基本的には大きなファイルでも 逐次処理できるはず です。

しかし、以下のような処理を書くと全体を一気に読み込むため、遅くなったりメモリ不足に陥ります。

# 全ファイルを1つのパターンスペースに取り込む
sed ':a;N;$!ba;s/\n/ /g' largefile.txt

この書き方は「全体を一度に処理する」ため、ファイルサイズに比例してメモリを消費してしまいます。

2. awkやperlとの比較

  • awk
    sedよりもテキスト処理が柔軟で、大規模ファイル処理でも比較的効率が良いです。
    例:ログから特定カラムを抽出するなどはawkが得意。
  • perl
    正規表現の表現力が高く、ストリーム処理も高速。大規模データの置換・整形ならsedより安定。
# sedでは重い全体置換をperlで
perl -pe 's/foo/bar/g' largefile.txt > out.txt

大きなファイルを扱うなら「awkやperlを選択肢に入れる」のは有効です。

3. sedで大きなファイルを処理するコツ

(1) ファイルを分割して処理する

Linux標準の split コマンドで分割し、sedで順に処理する方法です。

# 100MBごとに分割
split -b 100M largefile.txt part_

# 分割したファイルごとにsedを実行
for f in part_*; do
  sed 's/foo/bar/g' "$f" > "${f}_out"
done

# 結果を結合
cat part_*_out > final.txt

→ メモリエラーを避けつつ処理可能。

(2) ストリーム処理を心がける

sedは「1行ごとに処理する」使い方が最も効率的です。
N:a;N;$!ba;... などで全体を読み込むパターンを避け、
行単位で完結する処理に留めると安定します。

4. まとめ

  • sedで遅い/エラーになるのは「全体を一括処理」する書き方が原因
  • awkやperlのほうが大規模ファイルに向いているケースが多い
  • sedを使う場合は、splitで分割処理 or 行単位処理を心がける
よくあるエラーと解決方法まとめ
目次