Ripgrepが15.0に!多くの開発者を救ってきた「時間節約の神ツール」がさらに進化!
引用元:https://news.ycombinator.com/item?id=45627324
Ripgrepには長年、マジでお世話になってるよ!新しくシステムを立ち上げたら真っ先にインストールするくらい、今では欠かせないツールだね。古いコードベースを扱うのには必須だよ。
唯一の不満は、-F(リテラルとして扱う)オプションが、まだ特定の文字を特殊文字として扱っちゃうことかな。何の文字かは忘れちゃったけど。
更新され続けるのはいつも嬉しいね!
>-Fオプションが特定の文字をまだ特殊文字扱いしちゃう件。
もし具体的な例があれば、それについて説明できるよ。-F/–fixed-stringsは、パターン内の正規表現機能を100%オフにして、シンプルなリテラルとして扱われるはずだからね。エスケープが必要なのは、シェル側がそう要求してる場合かもしれないね。
-Fとーregexみたいな見た目のフラグはどう?コマンドラインの解析でフラグとして解釈されちゃってエラーになるよね。
-Fを使わないなら、シングルクォートで\-regexってハイフンをエスケープできるけど、固定文字列検索ができなくなっちゃう。そして-F \-regexは「バックスラッシュハイフン r e g e x」の固定文字列検索になっちゃうんだ。
唯一の方法は、正規表現を自分でエスケープして-Fを使わないことだね。-F=ーregexみたいな構文が使えるといいと思うよ。
うん、それは良い指摘だね。rg -F -e -patternってやればいいんだよ。
コマンドラインツールでは、--を使うことでオプションの終わりを示すのが慣例だよね。これ以降のものは、たとえダッシュで始まっていても通常の引数として解析されるんだ。もしRipgrepがこれをサポートしてないなら、すべきだね。
Ripgrepはリリース初日からサポートしてるよ。grepみたいに-e/--regexpフラグも使えるしね。
Ripgrepにはマジでお世話になってるよ!最近はLLMと一緒に使って、Ripgrepが使えることを教えてあげてるんだ。GitHubで寄付もしたよ、いつもありがとう!
全然話は変わるけど、jiffとchrono、time、std::timeなんかのセールスポイントって何?
あなたの仕事は本当に素晴らしい!僕たちは前から少しだけどスポンサーしてるんだ。いつも本当にありがとう!
https://docs.rs/jiff/latest/jiff/_documentation/comparison/i…とhttps://docs.rs/jiff/latest/jiff/_documentation/design/index…?を見てくれたかな?もっと具体的な質問があれば喜んで答えるよ。
個人的な意見だけど、jiffはより良いAPI、フットガン(予期せぬ挙動)の少なさ、より多くの機能、カレンダー期間のより良いサポート、統合されたtzdbサポートなど、正直もっとたくさんあるよ。
std::timeは、モノトニッククロックやシステムクロックへのプラットフォームに依存しないけど最低限のアクセスしか提供しないんだ。Unixタイムスタンプを単なる整数として扱う以上のことをしたいなら、何らかの日付時間ライブラリが必要になるんだよ。
rgは魔法みたいに感じるツールだよ。でも実際は、すごいエンジニアリングと改善への努力の結晶で、毎日使ってる素晴らしいハードウェアを活かしてるんだ。
それに、”lsp-like”な標準を待つ代わりに、agentがコードを速く探索・推論できるようにした「smithing」っていう点がすごいね。
この文脈での”smithing”って、マジで何のことか気になるんだけど!
”something”じゃないかな、たぶんね。
ごめん、ハハ。誤字に気づいた時にはもう遅くて、HNで編集できなかったんだ。誰も読み間違えないことを願ってたんだけど。
Ripgrepのコードベースは究極の「お酒を注いで、最高の椅子に座って、質の高いソフトウェアを読む」コードベースだよ。ちょっとクリックして見て回るだけで感動するはずさ。
このブログ記事もすごく良いから読んでみて!https://burntsushi.net/ripgrep/
fdと同じく、rgも使うの楽しいんだよね。新しいコマンドラインツールはやっぱり良いわ。
ripgrepとfdの作者がどちらもAstralで働いてるって今知ったよ。Astralが良いソフト作るのも納得だわ!
Astralってどんなビジネスモデルなの?
彼らはツールのうえにサービスを構築したいみたいだよ。3ヶ月前のこの記事を見てみて!https://news.ycombinator.com/item?id=44358216
pyxを企業向けに売ってるよ。https://astral.sh/pyx
rgもfdも、引数なしのデフォルト設定が99%のケースで欲しいものになってるのが良いんだよね。めちゃくちゃ時間節約になるわ。rg <string> fd <string>
今週、gitで追跡されてるファイルだけripgrepで検索する小さなbash関数rgg()を作ったよ。バイナリファイルやコミットされたドットファイルが多いディレクトリで、すごく速くなるんだ。ドットファイルを検索するのに-uuが必要なんだけど、そうするとバイナリファイルも検索しちゃうのが難点。何百ものファイルがあるリポジトリだとgit ls-filesのオーバーヘッドも少し大きいな。
それ、本当に速くなる例ある?ripgrepはデフォルトで.gitignoreを尊重してgit ls-filesに似た動きをするはずだよ。あと、-uuは.gitignore無視と隠しファイル検索だけど、バイナリはスキップ。バイナリも無視するなら-uuuが必要だよ。君のrgg関数をLinuxカーネルで試したら「引数リストが長すぎる」ってエラーに。xargs使ってもrg単体より遅かったし、どういう時に速くなるか具体例ある?
僕のリポジトリ[0](PDFや音声ファイル20GB)だと-uが遅いんだ。これらは.gitignoreとバイナリだから普段は無視されるんだけどね。.woodpecker内のCIファイルを検索したくて、前は-uuで4秒以上かかってたんだけど、-を使うと24msに短縮できたよ!git ls-files ...は40ms、rg -w. ...は24ms、僕のrgg ...は16ms、rg -wuu ...は2754msだった。試すなら20GBのバイナリファイル入れてみて。まあ、-フラグのおかげでこの議論も解決したけどね。[0] https://codeberg.org/vandenoever/rehorse
ああ、わかったよ。ripgrepで隠しファイルを検索すると、gitignoreで無視してるファイルも検索しちゃうと思ってたんだね。だからgit ls-files使ってたのか。うん、これで納得。-./--hiddenを使えば解決するもんね。教えてくれてありがとう!
これってgitignoreと同じじゃないと思うな。git ls-filesは追跡されてるファイルだけを検索するんでしょ?それならインデックス使う方が、ファイルシステムを直接見るより速いんじゃないかな。
俺、言葉を選ぶのにめっちゃ気を遣ったんだよ。もう一度引用するね、強調して言うけどさ、『ripgrepは基本的にgitignoreを考慮して、git ls-filesとほぼ同じ挙動になるはずだ』ってね。これも見てみて: https://news.ycombinator.com/item?id=45629515
ただ力になりたいだけで、君を責めてるわけじゃないんだ。gitignoreを考慮したファイルスキャンを自分で実装したことあるんだけど、追跡ファイルだけを探す場合だと、gitのネイティブ操作より遅かったんだよ。俺が話してたのは、意味じゃなくて速度のことね。
うん、git ls-filesがrg --filesより速いのは同意するよ。Chromiumのリポジトリで試したらさ、git ls-filesがrg --filesより2.57倍も速かった。でもripgrepは.rgignoreとか.ignoreも考慮しなきゃいけないし、Gitリポジトリじゃなくても.gitignoreを尊重するから、意味も大事なんだよね。
このコメント書いた後、マニュアルをもう一回読んだら、-uuの代わりに使える-.フラグを見つけたんだ。Gitが追跡してる隠しファイルを検索できるのは素晴らしいけど、Gitに問い合わせて全ファイルリストを取得するオーバーヘッドは、Rustでもかなり大きいだろうね。
もっとコメントを表示(1)
俺が見落としてるだけかな、でもripgrepってデフォルトでGitで追跡されてないファイルは無視するんじゃないの?
要は、Gitに追跡されてる隠しファイルを検索したいってことなんだ。例えば.woodpeckerとか.forgejo、.gitlab-ci-ymlみたいなCIスクリプトなんかは、そういう場所に入ってるでしょ。
これをもっとスマートにする方法として、こんなのはどうかな?printf ’!.woodpecker<br>!.forgejo<br>!.gitlab-ci-yml<br>’ > .rgignore
とかね。!を追加すれば、隠しファイルでもホワイトリストに追加されて、他の隠しファイルは無視しつつrgで自動的に検索できるようになるよ。ripgrep自体もリポジトリのルートにある.ignoreファイルで!/.github/を使ってるしね。https://github.com/BurntSushi/ripgrep/blob/38d630261aded3a8e…
それ、.rgignoreと~/.rgignoreにめっちゃ良い提案だね!
「これってgit grepより速いの?」
「いや、驚くべきことに(私にはね)、問題のリポジトリではgit grepがripgrep -w.やカスタムのrgg関数より2倍速いよ。
でもどれも100ms未満だから、十分速いね。」
「追加してほしいのは”extension”フラグかな。-gに似てるけど、引数を拡張子として扱うやつ(つまりrg -g ’*.{c,h}’じゃなくてrg -e c,h)。
globパターンを使う99%の時間は拡張子でマッチさせたいんだ。」
「-t/–typeフラグは使ったことある?君の例は-tcって書けるよ。
Ripgrepにない一般的なやつなら、自分でタイプを定義することもできるんだ。」
「使ったことあるよ、すごく便利な機能だよね。
でも、初めてカスタムglobを使いたい時に自分でタイプを定義するのはちょっと面倒に感じるな。長い目で見れば報われるんだろうけどさ。」
「素晴らしいツールだね、信じられないほど使いやすい。
Linuxで使い始めて、今は’dozeでも使ってるよ。
標準ワイルドカードで検索してから正規表現に切り替えるんじゃなくて、最初から正規表現を検索オプションとして使うようになったのは、たぶんこれが唯一の理由だな。」
「普通のgrepより優れてるし、便利なrg –filesもあるよ。」
「RipgrepがRustに興味を持った主な理由の一つだよ。
すごくうまく機能したから、Rustで書かれていることに興味を持ったんだ。何年か経ったけど、本当に嬉しいね。それ以来、毎日rgを使ってるよ!」
「QBasicはもう何年も使ってないけど、NibblesをハッキングしたからQBasicを学んだんだ。
その経験が、今AI教授になった理由の初期の大部分を占めていると言えるね。好きなソフトウェアが特徴の言語で遊ぶのは全然悪いことじゃないよ!」
Ripgrepは仕事で毎日使ってる。CLIでもVSCodeでも大活躍!burntshushiさんに感謝だよ。
最近—replaceや—typeオプションの便利さに気づいたよ。もっと早く知ってれば良かったな。これからはリリースノートもちゃんと読まなきゃね。JJとの連携も期待大だ!
新しいマシンを組む時、俺は真っ先にRustツールチェインとcargo install ripgrepを入れるんだ。数年前のBoston Rust meetupでの有限状態トランスデューサーの講演もすごく良かったよ。ソフトウェア開発と俺の学びへの貢献、本当にありがとう!
rgはLLM、特にClaudeやCodexが教えてくれた初のCLIツールなんだ。昔はgrep派だったけど、最近は指をrgに再教育中だよ。rgは本当に最高だね!
2017年にackへ、そしてagは飛ばしてrgへ乗り換えたよ。最近はfindじゃなくてfdも使い始めたんだ。1997年からターミナルを触ってるけど、新しい学びや改善されたコマンドを使えるのはマジで楽しいね。
俺はまだagを使ってるけど、rgに乗り換えるほどのメリットがわかんないんだよね。rgとagって、そんなに違うものなの?bashからzshにoh-my-zshで乗り換えた時みたいな感じかな。Nushellも最近気になってるよ。
Ripgrepはagより断然速くて(デカいファイルで違いがわかるよ)、バグも少ないし、ちゃんとメンテナンスもされてるんだ。
俺にとってはagも十分速いし、バグにも遭遇したことないんだ。返信ありがとう!君が誰だかわかったよ ;)
agのイシュートラッカーを見てみてよ。いくつか重大なバグがあるんだ。気づかないうちに影響を受けてるかもね。パフォーマンスは10倍くらい速くなるのをマジで体感できるよ。LinuxカーネルやChromiumリポジトリでのベンチマークも見てごらん。agはデカいファイルをスキップしちゃうこともあるんだよ。
俺はrgもagも長年使ってるけど、問題も速度差も感じないな。むしろ、rgで-iフラグを忘れて検索結果を見逃すことがあるのが残念。rgはパフォーマンス重視で、UXはちょっとイマイチって印象だよ。
スマートケースはデフォルトで無効の方がユーザー体験は良いと思うけど、–smart-caseフラグを使えば有効にできるよ。これはエイリアスか設定ファイルに追加できるね。agのスマートケース機能よりバグも少ないし、安定しているよ。
パフォーマンスの違いについては他のコメントを見てね。agはいくつか致命的なバグがあるし、もうメンテナンスされてないんだ。
検索するデータ量が少ないなら、動作が遅いgrepでもパフォーマンス的には問題ないことが多いよ。
機能リクエストには最適な場所じゃないのは分かってるんだけど、ripgrepが.githubディレクトリを隠しファイルだからって無視しちゃうのが最近すごく不便なんだ。デフォルトで含めてほしいディレクトリは他にもあるかもしれないね。
でも、もし急に検索結果に出てくるようになって、バージョンアップした人が後方互換性を期待してたら、そのトレードオフは割に合わないかもしれないけど。
>機能リクエストには最適な場所じゃないのは分かってるんだけど、ripgrepが.githubディレクトリを隠しファイルだからって無視しちゃうのが最近すごく不便なんだ。
このスレッドの他の場所でも提案されてるけど、リポジトリのルートにecho ’!/.github/’ > .ignoreってやってみた?ripgrepのリポジトリ自身もそうしてるよ: https://github.com/BurntSushi/ripgrep/blob/d47663b1b4548e4fa…
デフォルトで特定のディレクトリをホワイトリスト化してほしいっていうリクエストはあったけど、それは絶対にやらないよ。セマンティクスが複雑になるし、もっと分かりにくくなるからね。今は「ripgrepは.gitignoreを尊重し、隠しファイルとバイナリファイルを無視する」って言えるけど、もし特定のものをホワイトリスト化し始めたら、その説明は間違っちゃう。ripgrepのデフォルトのヒューリスティックを説明する時に、それらを例外として追加しなきゃいけなくなるもん。
それに、ディレクトリをホワイトリスト化するのはすごく簡単でシンプルだよ。みんな.ignoreファイルは無視するためだけだと思ってるみたいだけど、違うんだ。CLIコマンドをいじらなくても、無視しないようにできるんだよ。
>でも、もし急に検索結果に出てくるようになって、バージョンアップした人が後方互換性を期待してたら、そのトレードオフは割に合わないかもしれないけど。
ripgrepではsemverを使ってるよ。つまり、破壊的な変更を加える時はメジャーバージョンを上げるんだ。それでも、よほど強い理由がない限り、大きな破壊的変更は基本的にないね。semverは破壊的変更を許容するけど、ライブラリの文脈で一番うまく機能するんだ。直接エンドユーザーがいるripgrepにとっては、semverはあまり役立たない。ユーザーはただ、スクリプトが壊れたり、以前使えていたコマンドが動かなくなったり、違う動作をするようになったりするだけだからね。
fdについて教えてくれよ。俺はたまにfindを使うけど、ほとんどは-nameか-inameフラグを使うだけなんだ。
findと比べたらマジで一瞬だよ。それだけで十分だったわ。
-nameって1000回もタイプしなくて済むのがいいよね。
サンキュー。他の人向けだけど、Ubuntuでfdをインストールするならfd-findパッケージだよ。実行ファイル名はfdfind(ダッシュなし)だからね。
もっとコメントを表示(2)
検索はrgで始めるんだけど、パイプの後だと筋肉の記憶でgrep使っちゃうんだよね。
え、俺もそれやってたことに気づかなかったわ。grepは「パイプでフィルター」っていう位置付けが頭の中にあって、rgは「全ファイルを再帰的に検索」っていう位置付けなのかな。
俺もripgrepをリリースした当初はそうだったよ。今ではパイプの中でもrgを使うようにほとんど筋肉の記憶を再訓練したね。(特にrgがパイプの中でもgrepと同じように機能するように慎重に作ったからさ。)
あと、-o, –only-matchingと-r, –replaceを組み合わせることで、sedやawkの多くの用途を置き換えられることにも気づいたよ。
へぇ、俺も最近同じことに気づいたんだよね。意識してgrepじゃなくてrgを使うようにして、無意識に手が動くくらい覚え込ませようとしてるよ。
余談だけどさ、Ken Thompsonのオーラルヒストリーを見てたら、彼がgrepって名付けたらしいんだ。URL: https://youtu.be/OmVHkL0IWk4
これこそ質の高いソフトウェアだよね。
IntelliJのインデックス検索よりrgがずっと速いって、マジで驚くよね。
俺は500枚以上のヴィンテージMacintoshマガジンのCD-ROM(100万ファイル、解凍で3000万ファイル)からRipgrepでファイルリストを検索してるよ。データベースプログラマーじゃないけど、Ripgrepと同じくらい速くはできないし、正規表現でプレーンテキストを検索するのにこれで十分なんだ。URL: https://news.ycombinator.com/item?id=43607153
>.jjを含むディレクトリがgitリポジトリとして扱われるようになったって?これは本当に嬉しいな!
これがRustで書かれてなかったら、みんな気にしたかな?俺はまだgrep使ってるんだけど、それってダメなやつ?
ripgrepをgit grepに近づけるにはどうしたらいい?普通のrgだと.githubみたいな隠しフォルダは無視するし、rg --hiddenだと.githubは検索するけど.gitの中まで検索しちゃうんだ。俺は今、rg --hidden --glob ’!*/.git/*’ってエイリアスを使ってるけど、もっと良い方法はないかな?gitリポジトリの外でも動く方法がいい、git ls-filesをパイプするのはパスで。
これが役立つかも: https://news.ycombinator.com/item?id=45629497。特定の隠しファイルやディレクトリをホワイトリストに追加できるってことね。ripgrepはgitリポジトリの状態を読まないから、gitで追跡されてるファイルだけを検索するって正確に指示する方法はないんだ。.gitignoreを見て、隠しファイルとかバイナリファイルは自動で無視するだけだよ。だからgitっぽく使うには、検索したい隠しファイルをホワイトリストに追加するといいよ。gitと全く同じにしたいなら、git ls-files -z | xargs -0 rg ...ってやる必要があるね。
ripgrepができる前からThe Silver Searcher(ag)を使ってるんだ。ほんの少し速いだけの検索で、コマンドラインオプションが違うツールに切り替える必要はあんまり感じないんだよね。何かすごい機能を見落としてるのかな?
バグが減ってパフォーマンスが向上してるって?データ量にもよるけど、大量のデータを検索するなら10倍の差が出ることもあるよ:https://news.ycombinator.com/item?id=45629904
Ripgrepがagより優れてる点はたくさんあるぞ。
・Unicodeサポートが圧倒的に良い(agはほとんどない)
・--preでプラグイン可能なプリプロセッサ
・Jujutsuサポート
・UTF-16データを自動で検索できる
・PCRE2をサポート(agは数年前にEOLになったPCRE1だけ)
・-r/--replaceフラグで出力操作ができる。sedやawkの代わりに結構使ってるよ。
・Ripgrepはメンテされてる
・マルチライン検索がはるかにうまく動く
・2GB超のファイルも検索可能(agは無理っぽい)
・agには変なバグが多いんだ。
例としては、ag -c ’\w{8,} Sherlock Holmes’ sixteenth.txtが9って出すのに、cat sixteenth.txt | ag -c ’\w{8,} Sherlock Holmes’だと1が9回出たりとかね。
他にも、printf ’foo<br>bar<br>’ | ag ’foo\s+bar’だと何も出ないのに、rg -U ’foo\s+bar’だとちゃんと出る。
さらに、ag ’\w+ Sherlock Holmes’ full.txtだと2147483647バイトより大きいファイルはスキップされちゃうエラーが出るんだ。
まだあると思うけど、今思いつくのはこれくらいかな。
ありがとう!今rgを試してるところだよ。ただ一つ問題なのが、rgの-gフラグがagの-Gフラグほど表現力が低いってこと。agのはファイル名に正規表現を指定できるんだけど、rgのはglobしか使えないんだ。だから、よくあるケースではちょっとタイプ量が増えるし、柔軟性も少し低いね。
でも、UnicodeサポートってやっぱりNuclearなんだよな。Unicodeでは同じGraphemeでも色々な書き方ができちゃうし、Unicode非対応の言語固有の例えばueがüを表す場合なんか、ü自体もマークありと直接の二通りの書き方があるでしょ?そうなると、Ripgrepもugrepもそういう部分文字列は探し出せないんだ。アラビア語の微妙な違いもそう。マークの組み合わせだけじゃなくて、同じGraphemeを意味するもっと美しい文字もあるからね。
「still nuclear」ってどういう意味かわからないな。それに「unclear」じゃないの?
確かに、RipgrepはUnicodeのNormalizationはしてないよ。そんなツールは少ないしね。
でも、僕が言ったことが間違ってるわけじゃない。RipgrepにはagにはないたくさんのUnicode機能があるんだ。
NuclearはNuclearであって、Unclearじゃないよ。
Unicodeが文字列検索について何を言ってるか、通常のバイト検索grepツールとは対照的に、このレポートを読んでみて:https://www.unicode.org/reports/tr10/#Searching
>バグ修正が主で、ちょっとしたパフォーマンス向上とマイナーな新機能があるメジャーバージョンリリース
「バグ修正とパフォーマンス改善」って、ソフトウェアが肥大化する言い訳としてジョークみたいになってるのが悲しいよな。これはもっとひどい。「バグが減って速くなった」は少なくともほとんどの人が望むことだけど、「バグが減って速くなって、おまけに頼んでないランダムな変更も入った」なんて、全然嬉しくないね。
ファイル内容を検索するとき、検索文字列なしでrgを起動する方法ってある?
どういうこと?空のパターンを渡すこともできるけど、それだと全部マッチしちゃうよ。
もっと高いレベルでユースケースについて話してくれない?
返信ありがとう。fzfとrgを使ってファイル内容を検索したいんだけど、プレビューアを開いた状態で、最初にfzfを開いたときはrgに引数を渡したくないんだ。入力を始めてから検索したいんだよね。Telescope live_grepみたいな感じで。