web-dev-qa-db-ja.com

ソートされたファイルの間隔を効率的にgrepします

私のファイルは数百万行あり、メモリ/dev/shm/tmp.fileにあり、複数のスレッドからアクセスされます。

831092,25a1bd66f2eec71aa2f0a8bb3d,/path/to/a/file
4324,8d83c29e4d8c71bd66f1bd66fs,/path/to/another/file
...

そして、2番目の,の後の部分でsort -t , -k3でソートされます。一般に、各行の形状は[0-9]*,[0-9a-z]*,.*で、ファイルパスには\0または\n以外の任意の文字を含めることができます。

特定のディレクトリ内にあるすべてのファイルの行を、追加のコピーを作成することなく、可能な限り迅速に抽出する必要があります。ファイルはそのようにソートされているので、私が探している行はファイルの途切れのない塊です。

現在、私はgrep -F ',<directory>' /dev/shm/tmp.fileを使用していますが、最初のヒットのバイナリ検索を行ってから、チャンクを行ごとに展開するか、新しい行ごとにファイル全体を読み込まずに別のバイナリ検索を実行すると、はるかに速くなることを知っています。ただし、これはbashスクリプトに統合する必要があり、bashでlseekのようなことを行う方法は見つかりませんでした。

sgrep がありますが、行全体をソートする必要があります。

',<directory>'よりも速くgrep -Fですべての一致を抽出するにはどうすればよいですか?

編集:入力/dev/shm/tmp.fileは、この種の抽出を行うためにのみ存在します。したがって、ジョブを簡単にするために何らかの方法で前処理することはオプションです。

Edit:a.baa/bの間のソートは、すべてのサブディレクトリを含める必要があるため、問題ではありませんチャンク。

7
katosh

_831092,25a1bd66f2eec71aa2f0a8bb3d,/path/to/a/file_を_/path/to/a/file,831092,25a1bd66f2eec71aa2f0a8bb3d_に変更した場合

あなたはそれを行うことができます:

_look /path/to/ /dev/shm/tmp.file
_

lookは70年代の伝統的なUnixユーティリティであり、POSIXでは規定されていませんが、かなり一般的です。 Debianと派生物では、bsdmainutilsパッケージに1つあります。util-linuxにも1つあります(同じ名前のDebianパッケージではなく、BSDからコピーされます)。

lookmmap() sファイルを処理し、バイナリ検索を実行します。

ただし、Debianの実装では、_-b_オプション(ため息)を渡さない限り、grepの基本的な線形検索に戻ることに注意してください。したがって、Debianまたは派生物では、次のようになります。

_look -b /path/to/ /dev/shm/tmp.file
_

また、一部の実装では、処理できるファイルのサイズに制限があることに注意してください( Debianのパッチに対応するバグを参照

9