各行に1つの文字列を含む大きなファイルがあります。文字列がファイル内にあるかどうかをすばやく判断できるようにしたいと思います。理想的には、これはバイナリチョップ型アルゴリズムを使用して行われます。
一部のグーグルは、バイナリ検索アルゴリズムを使用して、指定されたプレフィックスで始まるすべての文字列を見つけて出力することを約束する-b
フラグを持つlook
コマンドを明らかにしました。残念ながら、正しく動作していないようで、ファイル内にあることがわかっている文字列に対してnullの結果を返します(同等のgrep
検索によって適切に返されます)。
このファイルを効率的に検索するための別のユーティリティや戦略を知っている人はいますか?
grep
とlook
には本質的な違いがあります。
特に明記されていない限り、grep
は行内のどこかにパターンを見つけます。 look
の場合、マンページの状態:
look —指定された文字列で行を表示しますbeginning
私はlook
を頻繁に使用していませんが、試したささいな例ではうまく機能しました。
多分少し遅い答え:
Sgrepが役立ちます。
Sgrep(sorted grep)は、ソートされた入力ファイルで検索キーに一致する行を検索し、一致する行を出力します。大きなファイルを検索する場合、sgrepは従来のUnix grepよりもはるかに高速ですが、大きな制限があります。
ここからソースをダウンロードできます: https://sourceforge.net/projects/sgrep/?source=typ_redirect
およびここのドキュメント: http://sgrep.sourceforge.net/
別の方法:
ファイルの大きさはわかりませんが、並行して試す必要があるかもしれません:
https://stackoverflow.com/questions/9066609/fastest-possible-grep
私は常に100 GBを超えるサイズのファイルでgrepを実行しますが、それはうまく機能します。
必要に応じてreally fast(O(1)fast)ハッシュセットを作成して調べることができます。事前に構築されたハッシュセットをファイルに保存してプローブできる実装を見つけることができませんでしたwithoutファイル全体をメモリに読み込む必要があるので、 自分でロールバックしました 。
ハッシュセットを構築します(-b
/--build
):
./hashset.py --build string-list.txt strings.pyhashset
ハッシュセットをプローブします(-p
/--probe
):
./hashset.py --probe strings.pyhashset \
'Is this string in my string list?' 'What about this one?'
…または標準入力で検索する文字列を使用:
printf '%s\n' 'Is this string in my string list?' 'What about this one?' |
./hashset.py --probe strings.pyhashset
終了ステータスのみに関心がある場合は、--probe
/-q
オプションを使用して--quiet
の出力を静止できます。
if ./hashset.py --quiet --probe strings.pyhashset ...; then
echo 'Found'
else
echo 'Not found'
fi
その他のオプションについては、-h
/--help
オプションまたは付属のREADME
ファイルからアクセスできる使用法の説明を参照してください。
sgrepはあなたのために働くかもしれません:
Sudo apt-get install sgrep
sgrep -l '"needle"' haystack.txt
プロジェクトページ http://sgrep.sourceforge.net/ のコメント:
Sgrepはバイナリ検索アルゴリズムを使用します。これは非常に高速ですが、ソートされた入力が必要です。
ただし、挿入については、データベースを使用するよりも優れたソリューションはないと思います: https://stackoverflow.com/questions/10658380/Shell-one-liner-to-add-a-line-to-a- sort-file/33859372#33859372
ファイルを断片にハッシュし、必要な部分だけをgrepできます。
for line in $(cat /usr/share/dict/american-english | tr '[:upper:]' '[:lower:]' | sort | uniq)
do
prefix=$(echo $line | md5sum - | cut -c 1-2)
mkdir -p $prefix
echo $line | gzip >> $prefix/subwords
done
ルックアップは次のようになります。
prefix=$(echo $Word | md5sum - | cut -c 1-2)
zgrep -m 1 -w Word $prefix/subwords
これは2つのことを行います。