大規模な記録記録のgrepを高速化する方法は?

大規模な記録記録のgrepを高速化する方法は?

.zsh_history現在、10,000行が無制限です。特定の文字列(たとえば)を持つすべてのコマンドを履歴で表示したいことがよくありますcurl。これhistory | grep curlによりgrep curl ~/.zsh_history、速度がはるかに高速になりますが、型が破損します(タイムスタンプは日付として解析されず、区切り文字は記号のままです)。

遅いパイプ転送のhistory問題を解決する方法はありますかgrep?人々がCtrl + Rをお勧めするのを見たことがありますが、明らかに同じではありません。 grepはリストCtrl + Rは一度に1つのコマンドを表示します。また、grepのパイピングを使用すると複数のgrepフィルタをリンクできますが、Ctrl + Rを使用すると同じ操作はできません。

答え1

まず、grepよりも複雑な操作をしない場合、限られた一致はhistory -m PATTERNおそらくgrepより速いでしょう。後で複雑なフィルタを適用しても、不要な-m線をほとんど削除する簡単なフィルタを追加してみてください。

制限要素が記録全体を印刷するのにかかる時間である場合は、historygrep(または他のフィルタ)によって選択された記録部分を印刷するハッキングがあります。使用fc -p新しい履歴レコードを開始し、レコードの選択された部分を読み取るようにします。テストされていません:

function format_history {
  fc -p -a =(cat)
  fc -l 1
}
history 1 | grep curl | format_history

これは使用するのに非常に便利ではありません(パイプの両側に何かが必要なので、プレフィックスだけを持つことはできませんmagic_history_filter)。高度なパイプを使用して一時ファイルを使用する必要があるため、レコード全体をフォーマットしないと取得速度が失われる可能性があります(zshはパイプレコードではなく検索可能ファイルからのみレコードを読み取ることができます)。

答え2

以下は、履歴全体ですべての文字列をすばやく検索できる簡単な機能です。

histgrep() {
  fc -lm "*${1}*" 1 -1
}

より速い速度:

histgrep() {
  zmodload -i zsh/parameter
  print -raC2 ${(kv)history[(R)*$1*]}
}

これらのうちの1つは各行の前に履歴行​​番号を出力するため、実行に必要な行を使用できます!<number>。たとえば、履歴行番号2596をコマンドラインに挿入するには、次の手順を実行します。

!2596

Tab次にまたはを押しますEnter

約3400行の履歴があります。私にはこれでhistgrep cd220行以上のコードが生成されましたが、関数の最初のバージョンは完了するのに約0.004秒しかかかりませんでした。

答え3

時には走ることもありますhistory >~/.zsh_history.cache。その後、そのファイルとhistoryファイルから欠落しているコマンドの出力をgrepできます。

私はzshそれに慣れていないので、ファイルの内容をコマンド出力と組み合わせるコードを提供することはできません。

答え4

ripgrepを試すことができます(https://github.com/BurntSushi/ripgrep)は実際にはより速く、便利なフィルタリングオプションがたくさんあります。 githubページには長い機能のリストがあります。

これは多くのディストリビューションのリポジトリにあります。

関連情報