メモリ使用量が原因でgrepが終了します。 grepがあまりにも多くのメモリを使用しないようにすることはできますか?

メモリ使用量が原因でgrepが終了します。 grepがあまりにも多くのメモリを使用しないようにすることはできますか?

私はOriginallist(dowork.sh Originallist)を見直しています。 clean1 は Originallist とは異なるようにソートされます。 dowork.shで処理する残りのコンテンツのリストを生成する必要があります。デフォルトでは、リストクリーニングR - リストクリーニング1 =リストクリーニング2です。これは否定的な仕事です。これを行うには、次のgrepオプションを使用できることがわかりました。

  • F は正規表現の代わりに完全な行一致を意味します。 (私たちはgrepがファイル名の文字について恥ずかしくて正規表現だと思うことを望んでいません。)
  • vは除外(例えば、マイナス記号演算)を意味します。
  • fは、与えられた単一の式(「ファイルからパターンを取得する」)ではなく、clean1ファイル内の式を探します。

# wc -l cleaned*
 9157094 cleaned1
 14283591 cleanedR

# du -sh cleaned*
1.3G    cleaned1
2.0G    cleanedR

# grep -Fvf cleaned1 originallist > cleaned2

5分間実行され、42G以下のメモリを消費しますが、これは大量で失敗して終了します。 clean2の長さは0バイトです。

末尾のclean2は14283591 - 9157094 = 5126497行長でなければなりません。

これはこのようなことを行う正しい構文ですが(私は10行長いcleanRと3行長いclean1でテストしました。結果clean2は7行長でした)、大量のメモリを消費します。あまりにも多くのメモリを消費せずにgrepを実行する方法はありますか?しばらく時間がかかることはわかりますが、同意します。

私は/tmp(私の場合はram)を使わずに他のディレクトリを使用できるようにする-Tオプションのようなものを探しています。

sort -h
 -T, --temporary-directory=DIR  use DIR for temporaries, not $TMPDIR or /tmp;
                                multiple options specify multiple directories

ベストアンサー1

sortコマンドは、比較的一般的なユースケースである大規模データセットを処理するための特定のサポート機能を提供します。巨大なgrepパターンは非常にまれなユースケースなので、開発者はこれに多くの努力を払うことを期待できません。

行の順序が重要でない場合は、ファイルの長さに関係なく、一度に数行以上メモリに保存せずに2つのファイルを並べ替えて比較できます。ソートにより、メモリ不足のファイルを処理できるため、これは効率的です。

sort originallist >originallist.sorted
sort cleaned1 | comm -23 originallist.sorted - >cleaned2.sorted

OriginalListの元の順序が重要な場合は、行番号を追加できます。

nl -w 22 originallist >originallist.numbered
# then generate cleaned1 from the numbered list

originallist.numberedソートされているので、これを実行して共通行を検索できますcomm

順序が重要で行番号を付けるには遅すぎる場合は、チャンクに分割してcleaned1各チャンクに対して単一のパスを作成することができます。originallist最近のGNU分割:

cp originalfile cleaned2.in
split -l 1000000 --filter='grep -Fxv -f - cleaned2.in >cleaned2.out; mv cleaned2.out cleaned2.in' cleaned1
mv cleaned2.in cleaned2

F「完全行マッチング」ではなく部分文字列マッチングを実行します。フル行ストリングマッチングの場合は-x。)

おすすめ記事