Find Files (Ff) – File Search Utility in Rust
github.com
github.com
Command | Mean [ms] | Min…Max [ms]
-------------|---------------|---------------
`fd .conf /` | 525.6 ± 17.7 | 505.3…552.0
`ff .conf /` | 1760.8 ± 10.2 | 1744.6…1775.3Further, it seems that this would IO-bound not CPU-bound so whatever small overhead exists in recursion vs iteration will not be noticeable.
I think the difference is rather that `fd` uses threads and `ff` does not.
Author here. This is true. ff does not use threads right now. I have started learning Rust just a few days ago. I am not quite yet familiar with advanced topics such as achieving parallelism using threads in Rust and other similar stuff. My knowledge of Rust is limited at this moment and I struggled to get the language concepts to work such as ownership, lifetimes, etc. I am sure that I will be able to improvise the ff's performance by some extent by gaining some more knowledge of Rust.
hope someone can produce a C version of them for fun
The C version of ripgrep is the thing that came before ripgrep, The Silver Searcher.
Second, the utility already exists, and this version is significantly slower:
> time ./ff '.*.cpp' ~/src/ > /dev/null
real 0m1.195s
user 0m0.488s
sys 0m0.671s
> time find -E ~/src/ -type f -regex '.*.cpp' > /dev/null
real 0m0.880s
user 0m0.407s
sys 0m0.425s
But wait! This is a totally unnatural use of find. If we use find like users actually do, we get even better performance: time find ~/src/ -name '*.cpp' > /dev/null
real 0m0.553s
user 0m0.181s
sys 0m0.363s
Hardly scientific. But it begs the question: who is this for? > ff '.*.js' ~/projects > /dev/null
5.79s user
14.77s system
97% cpu
21.024 total
> find -E ~/projects -type f -regex '.*.js' > /dev/null
3.98s user
10.76s system
67% cpu
21.933 total > ff '.*.js' ~/projects > /dev/null
7.59s user
24.21s system
337% cpu
9.413 totalalias ff='find . | egrep'
ff() { find . -regex ".*$1.*" "${@:2}"; };ripgrep is a Rust version of grep. It's the fastest grep I know and it has better Unicode support than GNU grep (because of Rust language decisions).
Looking at memory safety and portability it might also be a good idea to program them in Rust. There are whole classes of bugs that are excluded in Rust which still pop up every once in a while in some of our basic system tools.
I for one am very happy with tools such as ripgrep and fd which are more or less just rewrites of decades old programs but are much faster and have generally better though out interfaces.
Or doing this:
https://jugad2.blogspot.com/2015/07/no-thanks-we-are-too-bus...
e.g. ripgrep is faster and makes better use of available hardware (concurrency, SIMD) than grep – thanks to Rust.
This seems specious. If I started a grep implementation from scratch in C{,++}, it isn't clear to me that I couldn't achieve the same (or better) results as ripgrep. Comparing a totally rewritten program to one designed decades ago and concluding 'without Rust, we wouldn't have this faster program with better hardware use' doesn't seem quite right.
I have, though, said in the past that I wouldn't have written ripgrep without Rust, which is a very different claim and is opinionated, and mostly a statement about developer productivity and maintenance burden. With Rust, it is very easy to keep ripgrep's trains running across Windows, macOS and Linux.
Exa, ripgrep, fd, bat, broot, ruplacer
And more...
rg "^SECRET"
Find nothing. Try to contact someone who is asleep for half an hour, then they tell me they put it in there. grep -r "^SECRET" .
yep, it is there, in an .env file. "Uhh yeah sorry I was using ripgrep and it doesn't search hidden files by default but it has a flag for it" "you wut?" "nevermind, thanks bye." <- that is ripgrep. Maybe we got off on the wrong foot.Anyway thanks for listing all the tools you're great.
nurettin@ ~ () $ mkdir test
nurettin@ ~ () $ echo "TEST SOMETHING" > test/.env
nurettin@ ~ () $ cd test
nurettin@ ~/test () $ rg "TEST"
Why I don't know, because it has grep in the name? Do you now realize where the confusion might be lying?Some people might miss this, yes. That's why it's mentioned in the first couple sentences of the man page.
And yes, this most important bit of information is in the man page and the help text, but not at the top of the page people who came to actually download the tool will look first. Which is `https://github.com/burntsushi/ripgrep` .
The README mentions that it respects gitignore rules. I just updated it to include hidden/binary files. Thanks.
Still pretty sure grep is a confusing name for something which doesn't grep "because of smart filtering" <- that is just your rules, your way, whatever your heart desires, whatever you want to call "smart".
This is not about Rust anymore (which I actually like)
This is a point you seem to be ignoring in favor of opinions such as "this is the reason for this tool to exist" <- again, your way, your rules.
It is circular to name something after something else, then making it act totally different, whatever you want it to do, changing output format, filtering files, then responding to confused people saying hey this is what I wanted. Yes it is. It doesn't change a thing.
Thanks for the readme update.
> whatever you want to call "smart".
Related: https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#pos...
So in cases where the new "improved" tool departs from old standard [1], it just add one more thing, that can screw you, especially if it comes over as a replacement.
grepping for settings in dot files is not exactly a corner case for me.
And setting up aliases to me it's similar. It will just mess with you on systems when you don't have them set up.
I guess it depends what you primary use case is. I can see how a developer that spends most of his time on his desktop/laptop command line would find this good default.
[1] And that it does so silently. If something fails hard or errors on the side of not filtering, its less of an issue.
> So in cases where the new "improved" tool departs from old standard [1], it just add one more thing, that can screw you, especially if it comes over as a replacement.
The solution to this is so stupidly simple. If this is a problem for you, then _don't use the new tool_.
ripgrep is not a replacement for POSIX grep.
Repeat after me. ripgrep is not a replacement for POSIX grep. I've never once marketed it as such. Others might. Why? See the FAQ for an explanation.
> grepping for settings in dot files is not exactly a corner case for me.
It's not for me either. Why does everything have to be black and white? Just because it isn't covered by default doesn't mean anyone thinks it's a corner case. It is precisely because it is not a corner case that ripgrep makes it very easy to disable "smart" filtering.
And once again, of course, if you do not want to be bothered by this, then don't use the tool.
I don't expect ripgrep to change, or to cater to my needs, like you said I don't have to use it. I managed to figure that out on my own, but thanks anyway.
Perhaps I expressed myself poorly, or we are misunderstanding each other, but it doesn't really matter.
Thanks for writing ripgrep, I might not use the utility, but when I stared learning rust, ripgreps source was one of the sources I looked at as a nontrivial cli app.
Have a nice day.
ripgrep is no more "totally different" from grep than egrep (different regex syntax) and fgrep (not regexes at all) are.
For people who make grep an alias into rg, they can use, rg does have three compatibility modes: -u -uu and -uuu # see the manpage for details.
> Like other tools specialized to code search, ripgrep defaults to recursive directory search and won't search files ignored by your .gitignore files. It also ignores hidden and binary files by default.
I've got this in my .zshrc:
alias ls='lsd'
alias tree='lsd --tree'Tangent, but man is that a bad name for a CLI tool. Had to add a lot of keywords to not get drugs-related pages.
Though yes, many computer-thing names are bad in the search department.
And I'm totally impartial, being the author.
Joke apart, as I've been told broot was being mentioned here, I'm available if you have any question. I'll do a SHOW-HN post some day but I'm currently postponing it because of a bunch of new features in the making.
Reference: https://github.com/Canop/broot
These kinds of claims are much more interesting to me personally.
Modularity was not the issue. Complexity combined with concurrency was. Rust’s compile time checks was what made it feasible to be so aggressive without the bugs.
As far as I can tell, concurrency is fundamentally about grouping data by dependencies to find chunks that can be isolated. I think that resources are more about lifetimes and ownership and that resources and data aren't the same thing. This doesn't contradict what Rust is doing, it is more about relying on the language less.
You can see what I'm talking about in this link, though I don't think it has been digestible enough yet without video or examples.
https://github.com/LiveAsynchronousVisualizedArchitecture/la...
https://github.com/LiveAsynchronousVisualizedArchitecture/la...
[1] https://hacks.mozilla.org/2019/02/rewriting-a-browser-compon...
But with these tools, we have the freedom to revisit old assumptions. One of those is smart filtering. I can't tell you how many people tell me that they enjoy that as a good default.
Tools should make the fact that they do smart filtering very clear, because it can be surprising if you aren't expecting it. But otherwise, I'm not particularly sympathetic to your reasoning here because: 1) what I said above about standard tools being available and 2) these tools should have ways of disabling smart filtering. So if it bites you, it should bite you only once. After that, you either learn to like it, learn to setup an alias and forget about it, or ragequit the tool.
ag bug: https://github.com/ggreer/the_silver_searcher/issues/1233
Command line D utility - find files matching a pattern under a directory:
https://jugad2.blogspot.com/2016/10/command-line-d-utility-f...
The D stdlib's dirEntries() function makes the job easy, for a basic one like this.
I am not aperson who just has to use the newest and gratest for the sake of it, but I’d take ripgrep/rg over grep whenever I have the choice.
- It probably have more niceties than a 5min wrapper (color, friendly defaults, etc.)
I've personally used a homemade find wrapper for years, but have now replaced it with `fd` (another find reimplementation). The advantages isn't huge, but I find the niceties I never bothered implementing - well - nice :)
That being said: I did get burned by the default behavior of ignoring hidden files :D
Would've been nice if it by default didn't show hidden matches, but printed on stderr - something like:
$ fd thing
foo/something
...
>searching hidden files - ^C to abort<
>hidden files found (29) - use `--hidden` to show<