Hacker News new | past | comments | ask | show | jobs | submit login

I'm surprised that ripgrep is so low, at #227.

I've been using it instead of grep the last few months and I could never go back. Check it out if you haven't! Here is the repo and a technical breakdown by the author:



Probably in part because the_silver_searcher ('ag') which is a very similar tool is #65

It's the one I personally use simply because I discovered it before ripgrep came out. Plus the 'ag' commandline is super easy.

ripgrep's command line is `rg`, and it's much faster. When I first installed it I aliased `ag` to it to easy the transition.

How often do you handle files large enough to observe a difference between grep, ack, ag and rg ?

I'm willing to bet (and happy to lose) that most people, even in the subset who use grep "a lot" (defining "a lot"...), wouldn't see a significant improvement. They are people (I'm betting fewer) who need speed above all other concerns, and those people already make it to the top 1000.

The popularity of ripgrep, ag, ack, etc., is an object lesson in "defaults matter." I don't say this in the prescriptive sense, i.e., "hey, you, you should care about defaults!", but rather, in the descriptive sense, i.e., "there are a lot of people out there that care about the defaults." The second lesson to learn is that people care about the difference between "results are instant" and "there is a bit of noticeable lag." I don't personally care all that much, but other people do. (AIUI, some people use ripgrep in their fuzzy searchers, and maybe "instant" matters there. A lot of engineering went into ripgrep to make its directory traversal fast.)

Before I wrote ripgrep, I was a grep user. I hadn't migrated to ack or the silver searcher because I didn't see the need. (Sound familiar? :P) In my $HOME/bin, I had grepf:

    find ./ -type f -wholename "$1" -print0 | xargs -0 grep -nHI "$2"
and grepfr

    grep -nrHIF "$first" $@
And that was pretty much all I ever needed. If ack had never come along, I'm not sure I ever would have changed. The tools I had were good enough.

ripgrep didn't begin life as something that I intended to release as its own project. It began life as a way to test the performance of Rust's regex engine under similar work-loads as the regex engine in GNU grep. In other words, it was a benchmark that I used. (In fact, I used it quite a bit to reduce per-match overhead inside the regex engine. The second commit in ripgrep says, "beating 'grep -E' on some things.") I didn't really start to convert it to a tool that other people could use until I realized that it was actually as fast---or faster---than GNU grep. That, plus I was bored in an airport. :-)

A lot of people are happy with their tools that are good enough. I know I was. Has my life been dramatically changed by using ripgrep? No, not really. But I do like using it over my previous tools. It's a minor quality of life thing. It turns out, a lot of people care about minor quality of life things!

But yeah, I hear roughly the same sentiments that you say from a lot of people. All it really comes down to is different strokes and different common workloads that magnify the improvements in the tool.

Have you considered problem of printing searched results to terminal? I saw it is detailed little bit in your blog, but one of the things that bothers me is - say I am searchin for string "foo" in a 2GB log file. There are usual number of matches, nothing unusual.

But typically, I am not really looking for string "foo". I guess most users who are grepping log files are also looking for strings/text that appear slightly before and slightly after the match. This mostly happens when I am searching for an error/exception that triggered "foo". I find usability of grep frustrating when I need to search around something. It usually means, I have to restart the search with `grep -C` or something like that and even then line numbers I specified may not be enough.

Thoughts have crossed my mind, but it's a wickedly hard problem. My personal opinion is that once you start trying to solve the problem you're describing, then you really start to venture away from "line oriented searcher" to "code aware searcher" in a way that invites a lot of trade offs. The most important trade off is probably maintenance or complexity of the code.

In particular, in order to better show results, I kind of feel like the search tool needs to know something about what it's showing. Right? How else do you intelligently pick the context window for each search result? For code, maybe it's the surrounding function, for example.

The grep -C crutch (which is also available in ripgrep) is kind of the best I've got for the moment for a strictly line oriented searcher. `git grep` has some interesting bits in it that will actually try to look for the enclosing the function and emit that as context. I think it's the `-p/--show-function` flag. ... But that doesn't really help with your log files.

In any case, I am very interested in this path and even have an issue on the ripgrep tracker for it: https://github.com/BurntSushi/ripgrep/issues/95 --- I'm not sure if it really belongs in ripgrep proper, but I would really love to collect user stories. If you have any, that would be great. Examples of what you'd like the search results to look like would be great!

I use -C 20 combined with a pager.

rg foo -C 20 -p | less -R

Also, yuck, that command line. Glad I have those hidden behind shell scripts.

Hehe, yeah, I have `rgp` in my $HOME/bin:

    exec rg -p "$@" | less -RFX

First, thank you for your reply and your work.

Second, I include myself in the users of ripgrep (and the silver searcher before), I also dislike the slight waiting time when I have a better alternative.

Third, I'd like one those to be a default package in Debian.


> Third, I'd like one those to be a default package in Debian.

Yeah, I'd love that too! I know there have been people pushing on this, but AFAIK, it's stalled on "how do we package Rust applications in Debian."

(I don't use Debian and I'm not terribly familiar with their policies, so I'm not really familiar with the details.)

Rustc and Cargo are packaged for Debian; both are Rust applications. That shouldn't be the holdup.

Oh, I thought Cargo hadn't made it into Debian. I'm way behind the times then. :-)

It's not in stable, but it is in sid and buster. Now that rustc builds with Cargo, you gotta get both. :)

https://crates.io/crates/debcargo is also a big help.

> How often do you handle files large enough to observe a difference between grep, ack, ag and rg ?

> I'm willing to bet that most people, even in the subset who use grep "a lot" (defining "a lot"...), wouldn't see a significant improvement.

Daily, but not for the reasons that I think you're thinking. I work in Python a lot, which means there is typically a virtualenv in the tree somewhere, sometimes more than one. Typically, I want to search the code base itself — not a virtualenv, not the .git directory, etc. ripgrep, by default, will ignore entries in the .gitignore (and the virtualenvs are listed there, as they're not source, and cannot be committed), and repository directories like .git, and will thus not even consider those files. For my use case (searching my own code base), this is exactly what I want, and culling out those entire subtrees makes rg considerably faster than grep.

Yes — I could exclude those directories with grep by passing the appropriate flag. But it's time consuming to do so: ripgrep wins out by doing — by default — exactly what I need.

I also greatly prefer ripgrep's output format; the layout and colors make it much easier to scan than grep's.

Most of the people I've recommended ripgrep to are using grep, and passing flags to it to get it to do what essentially rg does quicker and/or by default. Ripgrep is an excellent tool.

(I used `git grep`, which is also considerably faster for similar reasons, prior to rg. But `git grep` requires a repository — for obvious reasons — and thus fails in cases where you're not in one. I often need to search several codebases when doing cross repository refactors, and ripgrep has been quite useful there.)

Possibly redundant information, but still: ag has those same features. I see lots of reasons to choose rg/ag over grep, but none yet to choose rg over ag.

ripgrep's gitignore support is more complete. ripgrep also supports seamless UTF-16 search, and can be made to search files of any number of other encodings as well.

But yes, the feature sets are very similar.

Well, the main would be speed, possibly even stability, (Rust vs C), but if you're not after those, there's little reason to choose rg over ag. On the other hand, speed is also the primary reason to go with ag over ack, so the question is, why not go with the fastest alternative?

Ripgrep’s antipitch [0] lists some reasons to prefer ag over rg.

[0]: http://blog.burntsushi.net/ripgrep/#anti-pitch

I intended to mention in my original post, but I appear to have forgot: I'm only comparing rg/grep; I have no experience with ag, so I can't speak to it. rg was my first "better than grep" tool, and it's filled my needs quite well. (Enough so that I've not felt the need to investigate ag.)

Every time I search in VS Code, which now uses rg by default.

You'll easily notice the difference on any recursive search. grep is really slow.

Depends on the size of the codebase you're grepping. I routinely deal with larger ones that I have to dissect and the difference is more than noticeable.

ripgrep wasn't released until late September last year or so, so it's missing a couple months of events based on that. Plus, it needed time to become popular. :-)

Thanks for the kind words!

Wow, rg looks fantastic! Will try it today I think...


I imagine a lot of people install it via cargo.

It’s also only very recently that the crown has passed from ag (the silver searcher) to rg.

I hate that ripgrep won't let you specify an arbitrary list of filename extensions to search. You have to do some voodoo to get it to only search .foo files. With ag it's as simple as -G foo.

It's better than ag in a lot of ways, but there are little pain points like that which make me shift back and forth between tools.

It seems that ripgrep looks at .gitignore files. You could write such a file to exclude glob-patterns.

You can't accomplish that with the -g glob flag?

  $ rg -g l foo
  No files were searched, which means ripgrep probably
  applied a filter you didn't expect. Try running again
  with --debug.
Empirically not! :)

EDIT: I see, you have to do "rg -g '*.l' foo". Well, that's a bit silly. Why force people to put asterisks inside of single quotes on the command line? Asterisks have a specific meaning in a shell setting. It's five times longer than -G l, the ag equivalent.

EDIT: Thanks for all the explanations.

`ag -G l` and `rg -g '{STAR}.l'` are not equivalent. The former will match any file name that contains `l` where as the latter will match any file name that ends with `.l`. (ag's -G flag accepts a regex with match-anywhere semantics, where rg's -g flag accepts a glob that matches on the basename of a file, e.g., `rg -g Makefile` will search all files name `Makefile`.)

The asterisk is part of standard globbing. You can also write it as `rg -g \{STAR}.l foo`, if you find that nicer.

If you want to match a list of extensions, then you can fall back to standard glob syntax: `rg -g '{STAR}.{foo,bar,baz}' pattern`. Or, as others have mentioned, if you're searching for standard file types, you can use the `-t/--type` flag. e.g., To search HTML, CSS and Javascript: `rg -tjs -thtml -tcss foo`.

Basically, ripgrep's `-g` flag is supposed to match grep's `--include` flag, which also uses globs and requires the same type of ceremony. I'd like to add --include/--exclude to match grep's behavior more precisely (which is based on user complaints wanting those flags).

N.B. Replace {STAR} in text above with a literal asterisk symbol.

>I see, you have to do "rg -g '.l' foo"

Actually it's just:

  rg -g '*.js' query
And if it's a known file type, like js, you can do (-t type):

  rg -g -t js
Why force people to put asterisks inside of single quotes on the command line?*

Because else the shell will auto-expand the asterisk before it even gets to rg, and rg will instead get the expanded list of files that match the pattern. E.g. if you have

  a.js b.js /foo
in a folder, then:

  rg -g *.js query
will be expanded by your shell to:

  rg -g a.js b.js query
and THEN run. rg will never see the asterisk in that case (and it also wont search inside /foo).

This is because of the shell, not the executable. The shell will translate `*` into a relevant list of files before passing them to the executable.

If you're using bash you don't need single quotes:

  rg -g*.l foo

`git grep` works just fine and it also pretty quick. i'm sure it isn't 100% the same use-case, but most of the time i'm looking inside a repo anyway, and for the other times i can just go get a coffee

The blog post linked in the GP contains benchmarks, including `git grep`. TL;DR is that for simple queries, `git grep` is going to perform about as well as ripgrep. For more complex queries, ripgrep can be faster.

If you're on Windows, ripgrep will also (seamlessly) search UTF-16.

i'm definitely not anti-ripgrep, but OP did say "I'm surprised that ripgrep is so low" - i'm not surprised at all, just trying to point out why.

it's just yet another tool which i'd have to learn, and yet another tool that isn't going to be installed on the remote machine.

is the productivity win worth installing it, let alone learning it compared to going from `grep` to `git grep`? for me probably not, diminishing returns. doesn't mean it isn't great software!

(also, for the sake of stats, homebrew is macOS only, although i appreciate the info)

Is it better than ack-grep?

I've been using ack-grep for years, seems fine.

It's a lot faster. See http://blog.burntsushi.net/ripgrep.

> Notably absent from this list is ack. We don’t benchmark it here because it is outrageously slow. Even on the simplest benchmark (a literal in the Linux kernel repository), ack is around two orders of magnitude slower than ripgrep. It’s just not worth it.

Speed is probably the main difference. I can't find direct comparisons, but ag is touted as faster than ack, and ripgrep as faster than ag.

The README contains a quick breakdown: https://github.com/BurntSushi/ripgrep#quick-examples-compari...

My blog post linked elsewhere goes into more detail, although I left out ack because it was too slow.

I forgot that I even had it on my system!

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact