[HN Gopher] fd: A simple, fast and user-friendly alternative to ...
       ___________________________________________________________________
        
       fd: A simple, fast and user-friendly alternative to 'find'
        
       Author : tosh
       Score  : 655 points
       Date   : 2025-03-19 11:44 UTC (1 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | snide wrote:
       | Big sharkdp fan. Ty you for making awesome software that i use
       | DAILY.
       | 
       | bat, fd, hexyl, hyperfine
       | 
       | I'm going to take this moment to remind all of you well-paid
       | engineers that if we each spread $10 a month sponsoring talented
       | software makers like sharkdp the Internet would be a better
       | place.
       | 
       | So many great little tools out there and we should try to support
       | an ecosystem for them.
        
         | seafoamteal wrote:
         | bat, fd, and hyperfine are all by the same person??? That's
         | incredible, I love all of these utilities.
        
           | agumonkey wrote:
           | Man should write a tutorial on writing good utility software.
           | Or teach even.
        
             | seanw444 wrote:
             | According to his website, he has:
             | 
             | https://shark.fish/rustlab2019
        
               | agumonkey wrote:
               | ah well, he pwned me i just wasn't aware of it :)
        
               | PaulDavisThe1st wrote:
               | I would not call that a tutorial on how to write good
               | utility software. It's a quite specific description of
               | how sub(1) was written, and it contains some useful
               | lessons, but not many that would apply to the broad class
               | of "utility software". I think.
        
           | jessekv wrote:
           | Seems like David Peter works at Astral now, as does Andrew
           | Gallant (ripgrep).
           | 
           | It's a dream team for rust cli tools over there.
        
             | danso wrote:
             | Was just going to say, the fd,bat author reminds me of
             | burntsushi (xsv, rg), in terms of the massive benefit
             | they've added to the *nix command-line ecosystem.
        
             | 1-more wrote:
             | I owe hours of my life to Andrew Gallant aka BurntSushi's
             | xsv. Nothing else tries to handle splitting long files into
             | N-row chunks [1]. I was using the command line utility, but
             | that's his wrapper around his rust-csv library. So if you
             | need CSV parsing in rust, I strongly recommend this
             | library.
             | 
             | [1] rows included linebreaks so your standard
             | sed/head/tail/something-from-coreutils approach would not
             | work.
        
               | singhrac wrote:
               | I have spent a lot of hours looking at `watch "xsv select
               | ... | xsv table"`.
        
               | 0cf8612b2e1e wrote:
               | Not that there is necessarily that much churn in csv
               | processing, but last I looked, the xsv repo has not
               | received much maintenance for a while.
        
               | barotalomey wrote:
               | When software is feature complete, fast and working
               | correctly, what is it exactly you expect to change?
        
               | 0cf8612b2e1e wrote:
               | I mean there are 131 open issues and some 30+ PRs, so
               | clearly people have some desire for change.
               | 
               | No criticism to the author. He is way more productive
               | than I will ever be, but xsv does appear to be on the
               | back burner. Open source means the author can spend their
               | time how they like and I am entitled to nothing.
        
               | chrishill89 wrote:
               | This is an active fork: https://github.com/dathere/qsv
        
               | n8henrie wrote:
               | IIRC it was just deprecated in nixpkgs for this reason
        
             | kiney wrote:
             | semi related: how does astral actually make money to pay
             | the devs?
        
               | Narushia wrote:
               | Astral is primarily funded by venture capital firms. The
               | head honcho, Charlie, has mentioned a few times that he'd
               | like to develop and sell services that integrate well
               | with Astral's open-source tools. However, nothing
               | concrete has been established or announced yet.
        
             | tandr wrote:
             | Same Astral as `uv` makers? Geez, these guys are
             | specializing on "making things go zoom-zoom"!
        
           | gjvc wrote:
           | https://github.com/sharkdp
        
         | mgrandl wrote:
         | You should also check out numbat. It's insanely good.
        
         | stared wrote:
         | Link for anyone interested: https://github.com/sharkdp
        
         | jhbadger wrote:
         | I'm glad you identified the author -- I'm a big fd and bat fan
         | but didn't know they were created by the same person. I'll have
         | to check out his other tools.
        
         | terminaltrove wrote:
         | in complete agreement, with tools like fd getting more
         | visibility!
         | 
         | we sponsored fd's development a while back and we occasionally
         | sponsor terminal tool authors from time to time at Terminal
         | Trove where we have more tools in the trove. (0)
         | 
         | we're currently sponsoring zellij which I encourage you to
         | check out and sponsor! (1)
         | 
         | https://terminaltrove.com/ (0)
         | 
         | https://github.com/zellij-org/zellij (1)
        
           | kstrauser wrote:
           | Hard agree about zellij. I used screen, then tmux, for years.
           | Zellij feels "right" for me in a way those never quite did.
           | It's brilliant.
        
             | aaplok wrote:
             | What differences between Zellij and tmux do you see as game
             | changers?
        
               | kstrauser wrote:
               | It's like so many other projects we're talking about
               | here: it has sane defaults. If you start Zellij for the
               | first time, it shows you menus to do all the things you
               | might want. A big plus is that it supports mouse
               | scrolling by default, and the scrolling works 100% of the
               | time as far as I can tell.
               | 
               | I don't know if it can do everything that tmux or screen
               | can do. I bet it probably can't. But it does all the
               | things I want such a thing to do, and without needing any
               | configuration on my part.
        
               | aaplok wrote:
               | Interesting. When I tried Zellij I found that the menus
               | were too much in my face, compared to tmux/screen more
               | minimal design. I see how this is a good thing when you
               | start using it but I wonder if it gets tiring in the long
               | run, in a clippy sort of way.
               | 
               | But yes it makes sense that this feature makes it
               | superior to tmux for some users. A good case for having
               | diversity in software.
        
               | kstrauser wrote:
               | I could see that. I use Emacs with all the toolbars etc
               | turned off. I get it.
               | 
               | I'm not a hardcore tmux user. I just like having
               | persistent sessions on remote machines and bouncing
               | between tabs, things like that. When I want to do
               | something beyond that, with tmux I'd have to RTFM each
               | time. In Zellij, the menu bar lets me discover it easily.
               | 
               | Bottom line: you're right. I'm glad they both exist!
        
           | wanderingmind wrote:
           | Never knew about Terminal Trove.looks like an awesome place
           | that collects a lot of useful terminal tools. This website
           | must be a separate HN posting.
        
         | numbers wrote:
         | I wish there was an easy way to find people to sponsor whose
         | repos I use (not depend on because every project I use
         | multiplies the same dependencies) but there are tools I use
         | daily that aren't dependencies in my project like wezterm or
         | atuin.
        
         | makapuf wrote:
         | Completely in line to put some money where my mind is regarding
         | opensource (just sponsored framasoft from another thread).
         | 
         | Do keep in mind how much how trillonaire/billionaire companies
         | sponsor the free software they use while doing so.
        
         | synergy20 wrote:
         | bat, fd, rg for me
        
       | oguz-ismail wrote:
       | $ touch $'a.\xFF'         $ find -name $'*.\xFF'         ./a.?
       | $ ./fd -e $'\xFF'         error: invalid UTF-8 was detected in
       | one or more arguments              Usage: fd [OPTIONS] [pattern]
       | [path]...              For more information, try '--help'.
       | $         $ touch III         $ LC_ALL=tr_TR.UTF-8 find -iname
       | 'iii'         $ LC_ALL=tr_TR.UTF-8 ./fd 'iii'         III
       | $
       | 
       | Every fucking time
        
         | coldpie wrote:
         | Can you elaborate on what's going on here? Something like "fd"
         | is assuming your filenames are UTF-8, but you're actually using
         | some other encoding?
        
           | oguz-ismail wrote:
           | fd is assuming the argument to -e is valid UTF-8 while
           | filenames can contain any byte but NUL and /
        
             | porridgeraisin wrote:
             | "I cook up impractical situations and then blame my tools
             | for it"
             | 
             | Nobody cares that valid filenames are anything except the
             | null byte and /. Tell me one valid usecase for a non-UTF8
             | filename.
        
               | coldpie wrote:
               | UTF-8 is common now, but it hasn't always been. Wanting
               | support for other encoding schemes is a valid ask
               | (though, I think the OP was needlessly rude about it).
        
               | porridgeraisin wrote:
               | It's backwards compatible with ascii right?
               | 
               | But yeah I suppose you would need support for all the
               | other foreign-language encodings that came in between --
               | UCS-2 for example.
               | 
               | But basically nobody does that. Glib (which drives all
               | GTK apps' and various other apps file reading) doesn't
               | support anything other than UTF8 filenames. At that point
               | I'd consider the "migration" done and dusted.
        
               | coldpie wrote:
               | The world is a lot more complicated & varied than you
               | think :) I was digging around in some hard drives from
               | 2004 just last weekend. At that time, lots of different
               | encodings were common, especially internationally.
               | Software archaelogy is a common hobby, it could be nice
               | to be able to use a tool like this to search through old
               | filesystems. "Not worth the effort" is definitely a valid
               | response to the feature request, but that also doesn't
               | mean there is absolutely no use for the feature.
        
               | jcranmer wrote:
               | I can definitely see a use case for supporting non-UTF-8
               | pathnames on disk (primarily for archaeological
               | purposes).
               | 
               | In a UTF-8-path-only world, what I would do is have a
               | mount option that says that the pathnames on disk are
               | Latin-1 (so that \xff is mapped to U+00FF in UTF-8, which
               | I'm too lazy to work its exact binary representation
               | right now), and let the people doing archaeology on that
               | write their own tools to remap the resulting mojibake
               | pathnames into more readable ones. Not the cleanest
               | solution, but there are ways to support non-UTF-8 disks
               | even with UTF-8-only pathnames.
        
               | porridgeraisin wrote:
               | Oh yeah I can imagine the pain for drives from that era.
               | I remember reading that sometimes you need the right
               | "codebook" - what was the word - installed and stuff like
               | that.
        
               | creeble wrote:
               | You do not have (or write programs for) filesystems that
               | contain loads of ancient mp3 and wma files.
               | 
               | It is the bane of my existence, but many programs support
               | all the Latin-1 and other file name encodings that are
               | incompatible with UTF-8, so users expect _your_ programs
               | to work too.
               | 
               | Now if you want me to actually _display_ them all
               | correctly, tough turds...
        
               | porridgeraisin wrote:
               | True. Btw curious, is there a defined encoding for text
               | in mp3 metadata? Or is that a pain too.
        
               | shakna wrote:
               | Running a shell script went badly, generating a bunch of
               | invalid files containing random data in their names,
               | rather than one file containing random data.
               | 
               | You wish to find and delete them all, now that they've
               | turned your home directory into a monstrosity.
        
               | dleink wrote:
               | nah, eff all that. Roll back the snapshot.
        
           | kccqzy wrote:
           | Right because file names are not guaranteed to be UTF-8.
           | That's the reason Rust has str and then OsStr. You may assume
           | Rust str is valid UTF-8 (unless you have unsafe code tricking
           | it) but you may not assume OsStr is valid UTF-8.
           | 
           | Here an invalid UTF-8 is passed via command line arguments.
           | If it is desired to support this, the correct way is to use
           | args_os https://doc.rust-
           | lang.org/beta/std/env/fn.args_os.html which gives an iterator
           | that yields OsString.
        
             | SAI_Peregrinus wrote:
             | No, OsStr is for OSes that don't encode strings as UTF-8,
             | e.g. Windows by default. Use Path or PathBuf for paths,
             | they're not strings. Pretty much every OS has either some
             | valid strings that aren't valid paths (e.g. the filename
             | `CON` on Windows is a valid string but not valid in a
             | path), some valid paths that aren't valid strings (e.g.
             | UNIX allows any byte other than 0x00 in paths, and any byte
             | other than 0x00 or `/` in filenames, with no restrictions
             | to any text encoding), or both.
        
           | burntsushi wrote:
           | What's happening here is that fd's `-e/--extension` flag
           | requires that its parameter value be valid UTF-8. The only
           | case where this doesn't work is if you want to filter by a
           | file path whose _extension_ is not valid UTF-8. Needless to
           | say, I can 't ever think of a case where you'd really want to
           | do this.
           | 
           | But if you do, fd still supports it. You just can't use the
           | `-e/--extension` convenience:                   $ touch
           | $'a.\xFF'         $ fd '.*\.(?-u:\xFF)'         a.
           | 
           | That is, `fd` requires that the regex patterns you give it be
           | valid UTF-8, but that doesn't mean the patterns themselves
           | are limited to only matching valid UTF-8. You can disable
           | Unicode mode and match raw bytes via escape sequences (that's
           | what `(?-u:\xFF)` is doing).
           | 
           | So as a matter of fact, the sibling comments get the analysis
           | wrong here. `fd` doesn't assume all of its file paths are
           | valid UTF-8. As demonstrated above, it handles non-UTF-8
           | paths just fine. But some conveniences, like specifying a
           | file extension, do require valid UTF-8.
        
         | ivanjermakov wrote:
         | I think it's common for tools to assume that file names are
         | valid unicode, not surprized.
        
           | SAI_Peregrinus wrote:
           | Common, but rather stupid. Filenames aren't even text. `fd`
           | is written in Rust, and it uses std::path for paths, the
           | regex pattern defaults to matching text. That said, it is
           | possible by turning off the Unicode flag. `(?-u:\x??)` where
           | `??` is a raw byte in hex. E.g. `(?-u:\xFF)` for OP. See "Opt
           | out of Unicode support[1] in the regex docs.
           | 
           | [1] https://docs.rs/regex/latest/regex/#opt-out-of-unicode-
           | suppo...
        
             | burntsushi wrote:
             | What is text? Are the contents of files text? How does one
             | determine if something _is_ text?
             | 
             | (I'm the author of ripgrep, and this is my way of gently
             | suggesting that "filenames aren't even text" isn't an
             | especially useful model.)
        
               | SAI_Peregrinus wrote:
               | Oh, I agree that "text" isn't well-defined. The best I
               | can come up with is that "text" is a valid sequence of
               | bytes when interpreted in some text encoding. I think
               | that something designed to search filenames should
               | clearly document how to search for all valid filenames in
               | its help or manual, not require looking up the docs of a
               | dependency. Filenames are paths, which are weird on every
               | platform. 99% of the time you can search paths using some
               | sort of text encoding, but IMO it should be pointed out
               | in the man page that non-unicode filenames can actually
               | be searched for. `fd`'s man page just links to the regex
               | crate docs, it doesn't generate a new man page for those
               | & name that.
               | 
               | As for "filenames aren't even text" not being a useful
               | model, to me text is a `&str` or `String` or `OsString`,
               | filenames are a `Path` or `PathBuf`. We have different
               | types for paths & strings because they represent
               | different things, and have different valid contents. All
               | I mean by that is the types are different, and the types
               | you use for text shouldn't be the same as the types you
               | use for paths.
        
               | burntsushi wrote:
               | I'd suggest engaging with this question, which I think
               | you ignored:
               | 
               | > Are the contents of files text?
               | 
               | It is perhaps the most prescient of all. What is the OS
               | interface for files? Does it tell you, "This is a UTF-8
               | encoded text file containing short human readable lines"?
               | No, it does not. All you get is bytes, and if you're
               | lucky, you can maybe infer something about the extension
               | of the file's path (but this is only a convention).
               | 
               | How do you turn bytes into a `&str`? Do you think ripgrep
               | converts an entire file to `&str` before searching it?
               | Does ripgrep even do UTF-8 validation at all? No no no,
               | it does not.
               | 
               | I'd suggest giving
               | https://burntsushi.net/bstr/#motivation-based-on-concepts
               | and the crate docs of https://docs.rs/bstr/latest/bstr/ a
               | read.
               | 
               | To be clear, there is no perfect answer here. You've got
               | to do the best with what you've got. But the model I work
               | with is, "treat file contents and file paths as text
               | until you heuristically believe otherwise." But I work on
               | Unix CLI tooling that needs to be fast. For most people,
               | I would say, " _validate_ file contents and file paths as
               | text " is the right model to start with.
               | 
               | > but IMO it should be pointed out in the man page
               | 
               | Docs can always be improved, sure, but that is not what
               | I'm trying to engage with you about. :-)
        
               | SAI_Peregrinus wrote:
               | I'd say some files are text, some are not. And I agree
               | that there's no good way to tell! I think ripgrep has a
               | _much_ harder job than fd, because at least fd can always
               | know that all paths it 's searching are valid paths for
               | the OS in use.
        
               | burntsushi wrote:
               | My point is that you can apply to the answer to the
               | question "are the contents of files text?" to the
               | question "are file paths text?"
        
               | SAI_Peregrinus wrote:
               | I get it. I think you're right that they both have the
               | same problem, but paths have a std type for handling them
               | that, while file content's don't. As long as you're on an
               | OS you can use std::path::Path (or PathBuf) for paths,
               | and ensure they're valid. I suppose I should have said
               | "Paths aren't Strings" or similar, they might be text but
               | they might not be, and fundamentally the issue is that
               | they're different data types. "Text" isn't universally
               | defined.
        
               | burntsushi wrote:
               | You can't really just use `std::path::Path` though.
               | Because it's largely opaque. How do you run a regex or a
               | glob on a `std::path::Path`? Doing a UTF-8 check first is
               | expensive at ripgrep's scale. So it just gets it to
               | `&[u8]` as quickly as it can and treats it _as if_ it
               | were text. (These days you can use
               | `OsStr::as_encoded_bytes`.)
               | 
               | `std::path::Path` isn't necessarily a better design. I
               | mean, on some days, I like it. On other days, I wonder if
               | it was a mistake because it creates so much ceremony. And
               | in many of those cases, the ceremony is totally
               | unwarranted.
               | 
               | And I'm saying this as someone who has been adjudicating
               | Rust's standard library API since Rust 1.0.
        
               | jakeogh wrote:
               | Tools must be general. Im not going to invest time using
               | a new one if it cant handle arb vaild filesystems. But
               | thats just me.
               | 
               | https://github.com/jakeogh/angryfiles
        
               | burntsushi wrote:
               | `fd` does, as pointed out in this thread in numerous
               | places. So I don't know what your point is, and you
               | didn't engage _at all_ with my prompt.
        
             | jcranmer wrote:
             | IMHO, the kernel should have filesystem mount options to
             | just reject path names that are non-UTF-8, and distros
             | should default to those when creating new filesystems on
             | new systems.
             | 
             | For >99.99% of usecases, file paths _are_ textual data, and
             | people do _expect_ to view them as text. And it 's high
             | time that kernels should start _enforcing_ that they act as
             | text, because it constitutes a security vulnerability for a
             | good deal of software while providing exceedingly low
             | value.
        
               | xorcist wrote:
               | So just turn off support for external media, which could
               | possibly be created on other platforms, and all old file
               | systems? Legacy platforms, like modern Windows which
               | still uses UCS-2 (or some half broken variant thereof)?
               | 
               | While I support the UTF-8 everywhere movement with every
               | fiber of my body, that still sounds like a hard sell for
               | all vintage computer enthusiasts, embedded developers,
               | and anyone else, really.
        
               | jcranmer wrote:
               | As I said in another comment, you can handle the legacy
               | systems by giving a mount option that transcodes
               | filenames using Latin-1. (Choosing Latin-1 because it's a
               | trivial mapping that doesn't require lookup tables).
               | UCS-2 is easily handled by WTF-8 (i.e., don't treat an
               | encoded unpaired surrogate as an error).
               | 
               | The reality is that non-UTF-8 filenames already break
               | most modern software, and it's probably more useful for
               | the few people who need to care about it to figure out
               | how to make their workflows work in a UTF-8-only filename
               | world rather than demanding that _everybody else_ has to
               | fix their software to handle a case where there kind of
               | isn 't a fix in the first place.
        
         | packetlost wrote:
         | Ok, but like, in practice this is a pretty weird edge case.
         | It's impractical and _usually_ worthless to have filenames that
         | can 't be described using the characters on a keyboard.
        
           | Galanwe wrote:
           | Which keyboard ?
        
             | packetlost wrote:
             | Any of them. File names are in the vast majority of cases
             | human readable in some character encoding, even UTF-8. You
             | would be hard pressed to find a keyboard/character code
             | that has characters that aren't represented in Unicode, but
             | it doesn't matter, just honor the system locale.
        
           | bravetraveler wrote:
           | Disagree, filesystems provide for both services and people...
           | this is an imposition. I, a mere human, may need my tools to
           | wrangle output generated by _other_ software that has never
           | once used a keyboard. Or a sensible character /set, bytes are
           | bytes
           | 
           | File extensions - or their names - mean absolutely nothing
           | with ELF. Maybe _$APPLICATION_ decides to use the filename to
           | store non-ASCII /Unicode parity data... because it was
           | developed in a closet with infinite funding. Who knows. Who's
           | to say.
           | 
           | Contrived, yes, but practical. Imposing isn't. The filesystem
           | may contain more than this can handle.
        
             | packetlost wrote:
             | My point is that it's such a weird edge case in the first
             | place that the chances of you needing to use a tool like
             | fd/find in this way is vanishingly small. I agree with the
             | general issue of treating file paths as encoded strings
             | when they are not. Go is the worst offender here because it
             | does it at the _language_ level which is just egregious.
             | 
             | Regardless, the point is moot because `fd` handles the
             | filenames gracefully you just need to use a different flag
             | [0].
             | 
             | [0]: https://news.ycombinator.com/item?id=43412190
        
               | bravetraveler wrote:
               | No more unusual than using "find" at all, is my point.
        
           | xorcist wrote:
           | Not at all. It's a common result of the resulting Mojibake
           | (https://en.wikipedia.org/wiki/Mojibake) after moving files
           | between platforms.
           | 
           | It's also what made Python 3 very impractical when it
           | orginally came around. It wasn't fixed until several versions
           | in despite being a common complaint among actual users.
        
         | 149765 wrote:
         | Had to lookup regex crate docs, but it's possible:
         | $ fd '(?-u:\xFF)'         a.
        
         | dspillett wrote:
         | It isn't wrong, 0xff _is_ invalid UTF8. Of course if your
         | locale is not set to UTF8 then that is a potential problem.
        
           | vsl wrote:
           | *nix filenames are series of bytes, not UTF-8 (or anything
           | else) strings. If a find replacement doesn't accept valid
           | (parts of) filenames as input, it's a bit unfortunate.
        
             | coldpie wrote:
             | If all you want to do is match against a sequence of bytes,
             | sure. But when you want to start providing features like
             | case-insensitivity, matching against file extensions,
             | globbing, etc, then you have to declare what a given byte
             | sequence actually represents, and that requires an
             | encoding.
        
               | oguz-ismail wrote:
               | > when you want to start providing features like case-
               | insensitivity
               | 
               | fd does that for English only. See the III/iii case in my
               | comment; iii capitalizes to III in Turkish, there's no
               | way to have fd respect that.
        
               | burntsushi wrote:
               | > fd does that for English only.
               | 
               | That's false. Counter-example:                   $ touch
               | 'D'         $ fd d         D
               | 
               | Your Turkish example doesn't work with `fd` because `fd`
               | doesn't support specific locales or locale specific
               | tailoring for case insensitive matching. It only supports
               | what Unicode calls "simple case folding." It works for
               | things far beyond English, as demonstrated above, but
               | definitely misses some cases specific to particular
               | locales.
        
               | jandrese wrote:
               | Casefolding is a minefield once you extend past English.
               | It is completely unsurprising to find problems with it in
               | other languages.
        
               | burntsushi wrote:
               | Yes. I'm the one who implemented the case folding the
               | `fd` uses (via its regex engine).
               | 
               | See: https://github.com/rust-
               | lang/regex/blob/master/UNICODE.md#rl...
               | 
               | And then Unicode itself for more discussion on the topic:
               | https://unicode.org/reports/tr18/#Simple_Loose_Matches
               | 
               | TR18 used to have a Level 3[1] with the kind of locale-
               | specific custom tailoring support found in GNU's
               | implementation of POSIX locales, but it was so fraught
               | that it was retracted completely some years ago.
               | 
               | [1]: https://unicode.org/reports/tr18/#Tailored_Support
        
       | tucnak wrote:
       | alias fd="rg --files | rg"
        
         | GCUMstlyHarmls wrote:
         | This isn't directly comparable, `fd` will find files with `X`
         | in the name, but the `rg` alias will find all paths with `X` in
         | it.
         | 
         | Eg,                   l mkdir wing && touch wing/xwing.exe
         | wing/tie.exe              l fd wing         wing/
         | wing/xwing.exe              l rg --files | rg wing
         | wing/tie.exe         wing/xwing.exe
        
           | tucnak wrote:
           | I guess you're right. Isn't the former more useful in
           | general? I find myself reaching for `:Rg` in Vim much more
           | often than `:Files` or `:GFiles` courtesy of fzf.
        
             | DaSHacka wrote:
             | They're just completely different tools.
             | 
             | The other day I was searching for a PDF I downloaded three
             | years ago from a certain company.
             | 
             | Simply ran `find ~/Downloads -iname ' _< company-name>_'`
             | and it immediately popped up.
             | 
             | rg would not have helped me there. Even if I used something
             | like rga, it would have taken significantly longer to parse
             | the contents of every file in my home directory.
        
       | kstrauser wrote:
       | I use the heck out of fd daily and it's in my standard
       | installation on new machines. I've used find for years and it's
       | great in its own ways, but convenient ergonomics isn't among
       | them.
       | 
       | I'm 100% on board with this recent-ish trend toward new
       | replacement utilities that may or may not retain all of the
       | flexibility of the originals but are vastly easier to use for
       | common cases.
        
       | agumonkey wrote:
       | As much as i love new rust cli tools, `fd` ended up in the same
       | bag as tar and ln.. I can never retain how to use it. I don't
       | blame anybody .. I'm just witness that I always have to re-read
       | the man from scratch to get anything done. And I'm not a gnu find
       | lover.. with all its idiosyncracies.. somehow it registers
       | better.
        
         | umanwizard wrote:
         | If you're having trouble remembering the order of arguments to
         | ln, remember that it's the same way around as cp. Worked for
         | me.
         | 
         | That is, if before there is something at /some/path but not
         | /another/path , after running                 ln /some/path
         | /another/path
         | 
         | there will be something there (same as cp).
        
           | agumonkey wrote:
           | thanks, i still need to ignore the fact that the link on the
           | right points to the left then
        
           | mturmon wrote:
           | This is what made the "ln" argument order click for me as
           | well.
           | 
           | Another piece of this parallel is that (with cp and mv) you
           | can omit naming the destination file - you often just name
           | the directory:                 cp /other/dir/foo.txt .
           | 
           | The corresponding shortcut with ln is not naming the
           | destination at all, and the symlink is created in the working
           | directory:                 ln -s /other/dir/foo.txt
           | 
           | Both of the above are my most common usage patterns, and the
           | abbreviation of the second argument in both helps reinforce
           | the parallel between cp, mv and ln.
        
           | stouset wrote:
           | The one that always trips me up is that `ln` is "dumb" about
           | how it handles the first argument.
           | 
           | If the first argument isn't an absolute path, it must be
           | relative to the second argument, and not to pwd.
           | ln ./foo ./bar/baz
           | 
           | ./bar/baz will be a symlink whose literal contents are
           | `./foo` so it will look for foo in the same directory (bar),
           | rather than in bar's parent directory.
           | 
           | This is totally backwards from how other utilities behave.
           | Which is completely understandable if you know what it's
           | doing under the hood. But it is counterintuitive and
           | surprising.
        
             | tavianator wrote:
             | At least with GNU coreutils, you can use `-r`/`--relative`
        
               | stouset wrote:
               | TIL!
        
             | bbkane wrote:
             | I've never internalized this, so I usually stick to using
             | absolute paths...
             | 
             | Not a solution for all problems, but it works for me most
             | of the time.
        
               | stouset wrote:
               | Absolute paths will break if, for example, the target and
               | source are in the same directory but you move the
               | directory.
               | 
               | Sometimes you semantically want absolute paths (I want to
               | symlink a thing to /bin/foo), sometimes you want relative
               | paths (I want to symlink a thing to something in a nested
               | directory).
        
         | nottorp wrote:
         | > As much as i love new rust cli tools
         | 
         | Why would you love them just because they're in rust?
         | 
         | I'd like to praise the author of this fd for not having "Rust"
         | all over the web page or in the HN link, actually.
         | 
         | The Rust inquisition would get far less pushback if instead of
         | threatening people that god will kill a kitten every time you
         | use a non-kosher programming language, they'd promote software
         | that improves (even opinionated improves, like this fd) on
         | existing tools instead of having its main feature "but it's
         | written in Rust!".
        
           | agumonkey wrote:
           | performance for a start
           | 
           | especially in the case of fd, it's way faster than gnu find
           | 
           | sorry if that annoys people, but a rust tool starts with a
           | high trust in my mind that it will fly
           | 
           | ps: to show i'm not in full fanboy mode, i'm often surprised
           | that fzf, brilliant and performant tool, is written in go,
           | but i know it's not rust :)
        
             | nottorp wrote:
             | > especially in the case of fd, it's way faster than gnu
             | find
             | 
             | ... also the only tool written in Rust that made it to HN
             | lately that does not scream "I'm written in Rust!"
             | everywhere :)
             | 
             | It also aims to improve on gnu find, not to reimplement it
             | because it's in a non approved language.
             | 
             | It's what the Rust evangelists aren't.
        
             | alp1n3_eth wrote:
             | Surprisingly, Go is great for CLI tooling. It may not have
             | the insane speed that carefully planned and written Rust
             | does, but it's very easy to write and be performant without
             | even needing to go to great lengths to optimize it.
             | 
             | I generally say that anything under 500ms is good for
             | commands that aren't crunching data, and even Python CLI
             | tools can come in under that number without too much
             | effort.
        
               | bbkane wrote:
               | Unfortunately, Python CLI startup time is correlated with
               | how many files the interpreter has to interpret, which
               | usually takes effort to combat, so larger CLIs that have
               | a lot of functionality and thus files always seem to slow
               | down.
               | 
               | The Azure CLI is a good example of this. It's been a year
               | or two since I used it, so maybe it's improved since
               | then, but it used to take a second or two just to run `az
               | --help`, which infuriated me.
               | 
               | If you own a slow Python CLI, look into lazily importing
               | libraries instead of unconditionally importing at the top
               | of each Python file. I've seen that help a lot for slow
               | Python CLIs at $DAYJOB
        
           | chrisweekly wrote:
           | That's a bit extreme. I'm not who you replied to, but IME,
           | things written in rust tend to be fast and sane. All else
           | equal, "written in rust" is a positive signal to me.
        
           | stouset wrote:
           | That is literally what people are doing. "Written in Rust"
           | has become a pretty convenient shorthand for "this was
           | written by someone who cares deeply about quality, and you
           | can guess that it will be extremely fast, relatively free of
           | bugs, and use as many cores as you want to throw at it".
           | 
           | While you're out here complaining, the Rust community has
           | built a truly impressive array of improved, human-focused
           | command line tools (rg, bat, fd, hyperfine, delta, eza, and
           | on and on) and a bunch of best-in-class libraries for
           | building tools (regex comes to mind).
        
             | dietr1ch wrote:
             | The ecosystem enables focusing on the task at hand. It's
             | great that you don't need to get side-tracked at every
             | single step. There's many high quality libraries.
        
             | BoingBoomTschak wrote:
             | While mostly true, there's a large problem with lots of
             | these Rust CLI tools (and I use some of them, don't
             | misunderstand me): they often discard the UNIX philosophy
             | in favour of newbie friendliness and glitter.
             | 
             | For example, ripgrep shouldn't merge find and grep
             | (actually, I use a personal wrapper around `find ... -exec
             | grep ... {} +` because my only beef with this is that
             | find's syntax to exclude stuff is horrible, https://git.sr.
             | ht/~q3cpma/scripts/tree/master/item/find_grep). Or you see
             | something like
             | https://github.com/shssoichiro/oxipng/issues/629 because
             | people don't even know how to use xargs...
             | 
             | Feels like if someone did a RIIR on ImageMagick, it'd be
             | able to talk with Instagram and Flickr by itself or process
             | RAW files like Darktable. Would probably have some kind of
             | tagging system too.
        
               | bbkane wrote:
               | I personally appreciate the newbie friendliness and
               | glitter, and even the "make the common case easier at the
               | expense of composability" tradoff, though I think tlmost
               | of these tools are still relatively composable.
        
               | burntsushi wrote:
               | I used a similar wrapper for years before I wrote
               | ripgrep. But now all of those wrappers are gone because
               | ripgrep covers all of their use cases (and then some).
               | I'm not a newb and I don't really care about glitter. So
               | I don't know where you're getting your condescension from
               | personally.
               | 
               | GNU grep discards the Unix philosophy in all sorts of
               | places too. Like, why does it even bother with a -r flag
               | in the first place? Did people back then not know how to
               | use xargs either? I mean, POSIX knew not to include
               | it[1], so what gives?
               | 
               | What's actually happening here is that what _matters_ is
               | the user experience, and the Unix philosophy is a _means_
               | , not an _end_ , to improve the user experience. It's a
               | heuristic. A rule of thumb to enable composition. But it
               | doesn't replace good judgment. Sometimes you want a
               | little more Unix and sometimes you want a little less.
               | 
               | Besides, you can drop ripgrep into a shell pipeline just
               | like you would grep. All that Unix-y goodness is still
               | there.
               | 
               | [1]: https://pubs.opengroup.org/onlinepubs/9699919799/uti
               | lities/g...
        
               | BoingBoomTschak wrote:
               | > GNU grep discards the Unix philosophy in all sorts of
               | places too.
               | 
               | Who ever claimed that GNU was a proponent of the UNIX
               | philosophy? Certainly not me.
               | 
               | > What's actually happening here is that what matters is
               | the user experience, and the Unix philosophy is a means,
               | not an end, to improve the user experience
               | 
               | Yes and no. The expression "user experience" implies that
               | all users are the same and benefit from the same
               | philosophy of software interface design.
               | 
               | > Besides, you can drop ripgrep into a shell pipeline
               | just like you would grep. All that Unix-y goodness is
               | still there.
               | 
               | The "Unix-y goodness" isn't only defined by what it can
               | do, but also what it _can 't_ do. I don't want to turn
               | this into a suckless rant, so I won't. Also, not having a
               | mode giving it POSIX grep compatibility really flies in
               | the face of that claim: I want my scripts to work on BSD,
               | MacOS and even Solaris/AIX without having to install
               | stuff.
               | 
               | ------
               | 
               | I know I may sound very smug but believe me when I say
               | that I really like some of these utils and the care put
               | into them (and I know you're the author of ripgrep) and
               | that I'm no UNIX OpenBSD user (Plan 9 exists for a
               | reason, and I favor CL over C/Go any time of the day).
               | But I really see them as optimizing for/targeting the
               | VSCode/Zed crowd, instead of the vim/emacs one, if you
               | know what I mean.
        
               | burntsushi wrote:
               | OK, so you phrased your criticism very narrowly toward
               | "lots of these Rust CLI tools," but in actuality, your
               | criticism applies way more broadly than that. Likely to
               | just about all of GNU's tooling, for example. And
               | probably BSD's and busybox's tooling too. Even busybox
               | isn't above implementing POSIX+some, and AFAIK none of
               | them provide a strict "POSIX only" mode.
               | 
               | Which is fine, but now your position is more "old man
               | yelling at clouds" than it is something specific about
               | the Rust tools. (And to be clear, I'm not above yelling
               | at clouds now and then.)
               | 
               | > Also, not having a mode giving it POSIX grep
               | compatibility really flies in the face of that claim
               | 
               | No... it doesn't? ripgrep being compatible with the Unix
               | philosophy is not the same as it being POSIX compatible.
               | I didn't say you could use ripgrep in any place you could
               | use grep in a drop-in compatible way. I said you could
               | use it in shell pipelines. As in, it inter-operates with
               | other tooling in a Unix-y way.
               | 
               | And besides, I don't know of _any_ grep that has such a
               | mode. How do you know you aren 't using a grep flag that
               | isn't available in other grep implementations?
               | 
               | > But I really see them as optimizing for/targeting the
               | VSCode/Zed crowd, instead of the vim/emacs one, if you
               | know what I mean.
               | 
               | Nope, I don't. I've been a vim (now neovim) user for
               | decades. And neovim even uses ripgrep by default over
               | grep if it's installed.
        
               | BoingBoomTschak wrote:
               | > OK, so you phrased your criticism very narrowly toward
               | "lots of these Rust CLI tools," but in actuality, your
               | criticism applies way more broadly than that.
               | 
               | Obviously. The topic was Rust CLI tools, that's why my
               | post focused on them. Indeed, my criticism is broader.
               | 
               | > Likely to just about all of GNU's tooling, for example.
               | And probably BSD's and busybox's tooling too. Even
               | busybox isn't above implementing POSIX+some, and AFAIK
               | none of them provide a strict "POSIX only" mode.
               | 
               | This isn't about POSIX or not POSIX, this is about
               | introducing yet another pure convenience feature for
               | something that can _easily_ be achieved with other
               | accompanying (guaranteed to be on the concerned platform)
               | tools. POSIX doesn 't create features anyway, it's about
               | describing things that have already become standard; the
               | Austin Group bug tracker is quite explicit about this.
               | 
               | > No... it doesn't? ripgrep being compatible with the
               | Unix philosophy is not the same as it being POSIX
               | compatible.
               | 
               | Well, just a question of interpretation of "Unix-like
               | goodness". UNIX is both a philosophy and a portability
               | standard (since POSIX == SUSv4). And as I said, doing one
               | thing and doing it well is another facet of that
               | philosophy; finding files != searching in them.
               | 
               | > And besides, I don't know of any grep that has such a
               | mode. How do you know you aren't using a grep flag that
               | isn't available in other grep implementations?
               | 
               | Compatibility != strict rejection of anything else, quite
               | obviously.
               | 
               | > Nope, I don't. I've been a vim (now neovim) user for
               | decades. And neovim even uses ripgrep by default over
               | grep if it's installed.
               | 
               | Which is why I said vim instead of neovim (even if neovim
               | is clearly better).
               | 
               | ------
               | 
               | I think you misunderstand my position because I like a
               | bit of snark: compromising on the "do one thing" part of
               | the UNIX philosophy isn't necessarily something horrible,
               | but it's not an imaginary issue either. I could give
               | other examples (like how the pretty clean xsv became
               | https://github.com/dathere/qsv) but it really doesn't
               | matter because I think it's more of a popular CLI "apps"
               | thing than Rust alone, even if there's community overlap.
        
               | burntsushi wrote:
               | I can no longer see any coherent point you're trying to
               | make.
               | 
               | My point is that you are treating an ideal ("do one thing
               | and doing it well") as an end instead of a means.
               | Moreover, you are treating it as if there is any actual
               | choice in the matter. In reality, the tooling most of us
               | use on the command line violates the Unix philosophy in
               | some way or another. So the question is not "should I
               | adhere to the Unix philosophy?" but "what makes a good
               | user experience?"
        
               | BoingBoomTschak wrote:
               | I don't see why my point is that hard to see: the "do one
               | thing" part of the UNIX philosophy is a good ideal to aim
               | for, even if often ignored in favour of a more convenient
               | kitchen sink approach. I then just mentioned that a good
               | majority of these useful Rust tools (I really like
               | hyperfine and oxipng, for example) don't seem to care
               | much about it.
               | 
               | Some example of that idea I use every day is
               | https://codemadness.org/sfeed-simple-feed-parser.html,
               | where feed parsing, serialization and visualization are
               | completely separated in small orthogonal binaries with
               | very few options. It could have been one fat "sfeed" or
               | something like its newsboat instead. (shilling it a bit
               | more there: https://world-playground-
               | deceit.net/blog/2024/10/sfeed-setup...)
        
               | stouset wrote:
               | > Who ever claimed that GNU was a proponent of the UNIX
               | philosophy? Certainly not me.
               | 
               | Nothing was specific to GNU in that comment. `-r` is
               | available in BSD grep too. You are being needlessly
               | pedantic and avoiding the actual points being made while
               | doing so.
               | 
               | > Yes and no. The expression "user experience" implies
               | that all users are the same and benefit from the same
               | philosophy of software interface design.
               | 
               | No, it doesn't. You have literally made that up out of
               | whole cloth, but it isn't how anyone else I'm aware of
               | defines "user experience".
               | 
               | As BurntSushi pointed out, ripgrep is even designed to
               | adapt to different means of use: as a standalone command,
               | as a utility in a pipe, and others. Improving the
               | usability for one use-case isn't necessarily at the cost
               | of others.
               | 
               | > I want my scripts to work on BSD, MacOS and even
               | Solaris/AIX without having to install stuff.
               | 
               | So your very reasonable desire to stick with POSIX for
               | shell scripts... means we shouldn't ever make new tools?
               | I'm genuinely failing to understand your point here.
               | 
               | In fact, having a "grep compatibility flag" would very
               | literally be the opposite of the UNIX philosophy you're
               | holding up elsewhere. ripgrep isn't grep. It isn't trying
               | to be grep. It's something new and different and (in some
               | use-cases) better. The old thing still exists and if you
               | want to use it for whatever reason... just do that?
        
               | BoingBoomTschak wrote:
               | > Nothing was specific to GNU in that comment. `-r` is
               | available in BSD grep too. You are being needlessly
               | pedantic and avoiding the actual points being made while
               | doing so.
               | 
               | Where's the actual point in "others do it too"?
               | 
               | > No, it doesn't. You have literally made that up out of
               | whole cloth, but it isn't how anyone else I'm aware of
               | defines "user experience".
               | 
               | That's not a question of definition, but of use in an
               | English sentence. If you say "this is good for user
               | experience", you implicitly group all users together. I
               | say some users prefer tools that do only one thing.
               | ripgrep itself acknowledges that "despite initially not
               | wanting to add every feature under the sun to ripgrep,
               | over time, ripgrep has grown support for most features
               | found in other file searching tools". And that's fine!
               | But not for everybody.
               | 
               | > As BurntSushi pointed out, ripgrep is even designed to
               | adapt to different means of use: as a standalone command,
               | as a utility in a pipe, and others. Improving the
               | usability for one use-case isn't necessarily at the cost
               | of others.
               | 
               | If I like the "finding files with auto filtering" part of
               | ripgrep, how can I use it to feed another grep or even
               | another tool? If it had been designed with the
               | aforementioned philosophy, it would have been "ripfind" +
               | "ripgrep" and maybe a "ripfg" pretty interface on top.
               | 
               | > So your very reasonable desire to stick with POSIX for
               | shell scripts... means we shouldn't ever make new tools?
               | I'm genuinely failing to understand your point here.
               | 
               | > In fact, having a "grep compatibility flag" would very
               | literally be the opposite of the UNIX philosophy you're
               | holding up
               | 
               | See my other reply: I love new tools, but "UNIX-like
               | goodness" is also about portability (as in SUS), not just
               | the philosophy. More of a misunderstanding than anything
               | else, really.
               | 
               | A flag would be impossible, but introspection based on
               | argv[0] (like Busybox) wouldn't be that far-fetched. But
               | yeah, clearly ripgrep isn't trying to replace only grep,
               | that was a mistake on my part.
               | 
               | As an addendum, the "UNIX philosophy" had a lot of crap
               | parts (e.g. bytes as universal interchange format) and
               | UNIX itself is a very poor implementation of said
               | philosophy (after all, g/re/p itself is pointless
               | porcelain over (s)ed, heh), I'm not sure discussing it
               | seriously without specifying which part (like "do one
               | thing") is very productive.
        
               | burntsushi wrote:
               | > If I like the "finding files with auto filtering" part
               | of ripgrep, how can I use it to feed another grep or even
               | another tool?
               | 
               | `rg --files`
               | 
               | Is your mind blown yet?
               | 
               | > is also about portability
               | 
               | Except for Windows.
        
               | BoingBoomTschak wrote:
               | Happy this was thought out! Still everything in one tool,
               | but glad modularity was truly considered.
               | 
               | > Except for Windows.
               | 
               | Of course POSIX portability doesn't apply to OSes which
               | intentionally ignore it. I think I have another flame
               | appreciating guy on the other side of the conversation =)
        
               | burntsushi wrote:
               | It just means that your claims about portability are, in
               | the real world, far less useful than is imagined. I ship
               | software to Windows users and the "portability" of POSIX
               | doesn't help there. Doesn't matter why to me. It just
               | means that I can't depend on POSIX for the "portability"
               | benefits that its proponents seem to cite so
               | enthusiastically.
        
               | umanwizard wrote:
               | > But I really see them as optimizing for/targeting the
               | VSCode/Zed crowd, instead of the vim/emacs one, if you
               | know what I mean.
               | 
               | At this point it sounds like you're making a purely
               | aesthetic/cultural judgment, rather than a technical one.
               | ripgrep works just fine with emacs; I have "C-c p s r"
               | bound to "run ripgrep in current project" and use it
               | almost every day.
        
             | alwillis wrote:
             | When I setup a new machine, the first two apps I install
             | are bat and eza.
             | 
             | Both are "must haves" as far as I'm concerned.
        
           | thiht wrote:
           | > Why would you love them just because they're in rust?
           | 
           | That's not it. People love the new rust tools because they're
           | great tools with sane defaults. They happen to be written in
           | Rust most of the time and that's it so people use this to
           | describe them.
        
         | bee_rider wrote:
         | For tar, I just remember tar czvf and tar xzvf.
         | 
         | Of course, then we get the question, ok, why not use a program
         | that just provides those options? But, I think all the extra
         | functionality of tar is nice to have sitting off there in the
         | background; I'd have to look it up if I actually wanted to use
         | it, but it is all there in the documentation, and nicely
         | compatible with the files produced by my memorized commands.
        
           | sitkack wrote:
           | Fully laden Gnu tar or BSD tar?
        
             | bee_rider wrote:
             | I guess GNU most likely. On my system, it's just Ubuntu,
             | and on the server side, it is, I guess, whatever the
             | administrator installed, haha.
        
             | kiwijamo wrote:
             | Both commands work in either I believe. I've been using
             | both since my FreeBSD days and now I use Debian Linux with
             | no change.
        
           | mitsu_at wrote:
           | Reminded of this xkcd :P https://xkcd.com/1168/
        
         | porridgeraisin wrote:
         | > tar
         | 
         | I remember only two flags for tar. That's it.
         | tar -x       tar -c
         | 
         | c for create, x for extract.
         | 
         | I use it like so:                 tar -c src | gzip >
         | src.tar.gz
         | 
         | and extracting like                 curl
         | https://source.code/src.tar.gz | gunzip | tar -x
         | 
         | That's all.
         | 
         | The core operations taking up only this much headspace leaves
         | the door open to slowly start to retain all its other useful
         | options. For example, -v, which means verbose almost
         | everywhere, thankfully means verbose here too, so I add that
         | when I want verbosity.
         | 
         | Similarly, I find it easy to retain -l which lists the
         | contents. I do this quite often for stuff from the internet --
         | I don't like it when I untargz in ~/Downloads and it untargz's
         | it in the same directory instead of doing everything inside a
         | parent directory (preferably with the same name as the archive)
         | 
         | Bonus: separating out the gzip like this makes it easy to
         | remember how to use zstd if you want to, just pipe to zstd
         | instead! "Unix philosophy" and all that.
         | 
         | I agree with you about `ln`, I can never seem to remember if
         | it's source or target that comes first.
        
       | grenran wrote:
       | annoyingly fd also stands for file descriptor
        
       | travisgriggs wrote:
       | I'll have to try this out. I admit that most of my uses of find
       | looke like
       | 
       | find . | grep what_i_am_looking_for
       | 
       | Because I can never remember how finds arguments work. I like the
       | integrated xargs like behavior as well.
       | 
       | One thing I did not see in there was how fd handles symlink
       | directory traversal? Searched the whole readme for it, and only
       | found options to match on symlinks or not.
        
         | xiphias2 wrote:
         | That's basically rg
        
           | jorams wrote:
           | No, rg looks inside files. find . | grep just lists all files
           | and directories and then filters it down using grep.
        
             | dietr1ch wrote:
             | You may want `fd | fzf` or fzy instead. That way you can
             | filter and select interactively
        
         | diziet_sma wrote:
         | fd --help | rg link -C 10
         | 
         | Set -L --follow to descend into symlinked directories. The
         | default is to not.
        
         | bee_rider wrote:
         | I'm finding that I use locate more and more for this sort of
         | thing. Of course, it produces a lot more output, because it
         | looks at the whole system. But, it is still much faster than
         | find because it runs on some kind of index or something, and it
         | is easy enough to grep out the directory I'm interested in, if
         | needed.
        
           | gcmeplz wrote:
           | locate is nice, but I think that on most distros its index is
           | only updated once/day (unless you adjust the cron job that
           | updates it more often). Most of the times I'm trying to find
           | something, I haven't modified it recently, but it can
           | definitely lead you astray.
        
             | silisili wrote:
             | One can just run 'sudo updatedb' to refresh it. Super fast
             | if it's already on a schedule. I think mine is set to
             | update every system update, so I just have a habit of
             | running that before I use locate each time.
        
         | VTimofeenko wrote:
         | Check out `curl cht.sh/${utility_name}`. It will print a short
         | help page with some common examples
        
           | hnlmorg wrote:
           | Shameless plug:
           | 
           | Or just press F1 if you use my shell.
           | 
           | https://murex.rocks/user-guide/interactive-
           | shell.html#autoco...
        
             | helsinki wrote:
             | Hm, I feel like I have roughly the exact same functionality
             | with zsh and some various plugins, including the meta
             | editing experience shown in your demo video ($EDITOR) via
             | Kitty and/or WezTerm.
        
               | moozilla wrote:
               | Which plugins are you using? I've been looking to upgrade
               | my zsh experience so some suggestions would be helpful.
        
               | hnlmorg wrote:
               | With some effort it's possible to bend zsh to any
               | workflow, but there's a lot to be said for having sane
               | defaults.
               | 
               | The other value add for alternative shells like my own is
               | better support in the language for handling structured
               | data (is not treat everything as a dumb byte stream).
               | 
               | Ultimately though, productivity is all about familiarity
               | and if you're also super efficient in zsh then I'm not
               | going to try and convince you that some shiny new tool is
               | better.
        
         | kjkjadksj wrote:
         | Why pipe to grep instead of applying the pattern in the find
         | command?
        
           | pimlottc wrote:
           | > Because I can never remember how finds arguments work
        
         | layer8 wrote:
         | In that case, you might as well just use _grep -r_ , or its
         | alias _rgrep_. And then remember that it supports _--
         | include=GLOB_ , _--exclude=GLOB_ , and _--exclude-dir=GLOB_.
         | 
         | (That's GNU Grep, just to be clear:
         | https://www.gnu.org/software/grep/manual/grep.html#File-
         | and-...)
        
           | yread wrote:
           | Err no? grep searches contents and op is looking in filenames
        
           | ltbarcly3 wrote:
           | nope, not remotely the same thing
        
           | forinti wrote:
           | Not the same thing, but thank you. I've been using "find .
           | -type f -exec grep -i {} /dev/null \;" without looking for a
           | better solution and here it is.
        
         | timewizard wrote:
         | You're just using the unix pipeline as it was intended. I
         | always prefer this over having to remember a bunch of obscure
         | command line switches.
        
       | meisel wrote:
       | Personally I prefer bfs (https://github.com/tavianator/bfs)
       | because it does a breadth-first search
        
         | tavianator wrote:
         | Someday I will get that functionality into fd :)
        
           | meisel wrote:
           | Looking forward to it!
        
       | actinium226 wrote:
       | Is anyone else bothered by the fact that by default it ignores a
       | lot of folders? I use `find` when I'm like 'I just want to know
       | where on my system this is, wherever it might be'
       | 
       | I know fd has options to not ignore things, but I can never
       | remember them, so I just go back to find because I know it'll
       | search everything.
        
         | burntsushi wrote:
         | ripgrep has the same default behavior.
         | 
         | You just want `fd -u`. Or in ripgrep's case, `rg -uuu`.
         | 
         | `fd`, I believe, got `-u` from ripgrep. And I can say that
         | ripgrep got its `-u` from `ag`.
        
         | jandrese wrote:
         | Same thing that drives me crazy with Windows built-in file
         | search. The Windows one ignores AppData, which is where
         | everything gets stashed these days.
        
           | Joe_Cool wrote:
           | I completely dumped the windows search and only use
           | voidtool's Everything when I am on a Windows box.
           | 
           | It can search multiple indexed NTFS drives in miliseconds.
           | Indexing is usually a few seconds since it works directly on
           | the NTFS structures. (and it integrates with Total Commander)
        
           | ajolly wrote:
           | You should check out void tools search everything!
        
         | kstrauser wrote:
         | That's a feature, and one of the reasons I prefer it. When I
         | want to find a file in a git repo, say, there's no need looking
         | inside .git most of the time. Sometimes there is: if I don't
         | remember `fd -u`, there's good old find there for me. But
         | that's almost never what I want to do, so fd's defaults are
         | sensible for me.
        
         | pantsforbirds wrote:
         | I actually prefer it. It's very similar to ripgrep's default
         | search. I do occasionally want to find something in a
         | .gitignore, or other hidden directory, but I don't mind taking
         | the time to `rg/fd --help` and add the flag to include hidden
         | directories.
        
         | eredengrin wrote:
         | Same, this is why I haven't fully converted to lots of these
         | newer tools. If I have to remember a bunch of special flags to
         | make them look at the files I need them to, their advantage is
         | lost. I'm better off using the originals and solidifying those
         | flags in my muscle memory since at least those tools will be on
         | any system I use. I do use ripgrep on occasion but not very
         | often.
        
         | jpeeler wrote:
         | Same, I never remember them either. However, I use a shell
         | (fish) that has decent command history autocompletion that
         | helps a lot for such things.
         | 
         | I wish the flags between ripgrep and fd lined up as I think
         | that's what confuses me (can't remember now haha).
        
       | sandos wrote:
       | Yeah, I was trying the -exec functionality of find just
       | yesterday, something which Iv'e done many times before, but that
       | was long ago.
       | 
       | I eventually gave up! Thats how ergonomic find is :)
        
       | rednafi wrote:
       | One reason I haven't picked up any of these newfangled Rust tools
       | like bat, exa, or fd is that I can barely remember the options
       | for the originals.
       | 
       | For me, anything that isn't a drop-in replacement for the OG
       | tools isn't worth the friction. I use ripgrep inside VS Code but
       | vanilla grep on the command line because of years of muscle
       | memory.
       | 
       | That said, I don't care what language a tool is written in as
       | long as it works. One of my favorite Unix tools is GNU Stow, and
       | it's written in Perl. Even if these Rust tools were drop-in
       | replacements, I probably wouldn't bother installing them
       | manually. As a user, the speed improvements and memory safety
       | don't really matter to me.
       | 
       | There are other languages, like Go, where memory safety is
       | guaranteed as well, and Go's performance is more than adequate
       | for tooling--with the added benefit of getting more engagement
       | from the community. So I'm not entirely convinced by this "Rust
       | is the savior" narrative.
       | 
       | That said, if macOS or Ubuntu decided to hot-swap the OG tools
       | with Rust alternatives that behave exactly like their
       | predecessors, I probably wouldn't complain--as long as it doesn't
       | disrupt my workflow.
        
         | johnisgood wrote:
         | > One of my favorite Unix tools is GNU Stow
         | 
         | What about https://zolk3ri.name/cgit/zpkg/? A lot of
         | improvements have been done behind the scenes apparently
         | (rollback, proper states, atomicity, etc.), but I am not sure
         | when he is willing to publish.
         | 
         | I personally use it as-is when I am compiling stuff myself and
         | the ZPG_DST is ~/.local/. It works well for keeping track of
         | programs that I compile and build myself.
        
         | whompyjaw wrote:
         | It absolutely does not matter what language this tool is
         | written in. That goes for any tool. If it's better, use it. In
         | this case, fd is far superior to "find" in almost every way.
         | Sane defaults, wayyy faster, easy options (just use cht.sh if
         | you can't remember) To me, there is no reason to ever use
         | "find". If I'm on a new system, I just install fd and carry on.
        
           | syklemil wrote:
           | > It absolutely does not matter what language this tool is
           | written in. That goes for any tool.
           | 
           | Eh, there are a lot of tools where it actually does kind of
           | matter. I suspect for a lot of invocations of tools like `fd`
           | and `rg`, they'll be done before an equivalent written in
           | java has even had its JVM spin fully up.
           | 
           | There's _tons_ of Java software, but it somehow never managed
           | to make a dent in the CLI space.
           | 
           | > To me, there is no reason to ever use "find". If I'm on a
           | new system, I just install fd and carry on.
           | 
           | I guess I should finally have a look at how to replace my
           | `find $path -name "*.$ext" -exec nvim {} +` habit ... turns
           | out it's `fd -e $ext -X "nvim" "" $path`
        
           | graynk wrote:
           | it tangentially matters, because cargo is so good that I use
           | it instead of a package manager for all these fancy rust
           | tools
        
         | jhbadger wrote:
         | >One reason I haven't picked up any of these newfangled Rust
         | tools like bat, exa, or fd is that I can barely remember the
         | options for the originals.
         | 
         | But that's exactly the reason _to_ use the newer tools -- they
         | just make more sense -- especially fd over find. I 've been
         | using UNIX for over thirty years and find just never clicked
         | with me.
        
           | TylerE wrote:
           | Confession; the only way I've ever actually used find is just
           | a tree walker piping to grep to actually find whatever.
        
           | quinncom wrote:
           | fd is probably better for most tasks, but sometimes it seems
           | more cumbersome than find. E.g., to delete all files inside a
           | cache directory, this is the simplest syntax I could find:
           | 
           | fd -t f -X rm {} \; ^ cache
           | 
           | Which makes me really nervous, so usually I fall back to
           | using find:
           | 
           | find cache -type f -delete
           | 
           | Maybe this is foolproof for me only because I've been using
           | find for decades. Is there a version of this for fd that
           | inspires more confidence?
        
             | orlp wrote:
             | I would suggest                   fd -t f . cache -X rm --
             | 
             | Which reads as find "any file", "matching .", "in directory
             | cache", then "execute rm -- followed by an argument list of
             | all found files".
             | 
             | This ensures even if you have filenames starting with -
             | they won't be interpreted as options for rm. For even more
             | sanity of mind you may want to turn on -a for absolute
             | paths, although I don't see an example right now where
             | using relative paths would go wrong.
        
         | BeetleB wrote:
         | If you're already proficient with grep, find, etc - there's not
         | much reason to switch. As I said elsewhere:
         | 
         | I never managed to use find because I always had to look up
         | command line arguments. I would always find a different way to
         | solve my problem (e.g. Midnight Commander).
         | 
         | I use fd all the time.
         | 
         | A better interface makes a big difference.
        
           | thayne wrote:
           | > there's not much reason to switch
           | 
           | There are a few reasons you might still want to switch. In
           | fd'a case:
           | 
           | - It respects .gitignore files (as well as similar .fdignore
           | files that aren't git specific), which can help you find what
           | you care about without a lot of noise, or having to pass a
           | lot of exclude rules to find
           | 
           | - it can search in parallel, which can significantly reduce
           | latency when searching large directories.
           | 
           | However, there are also reasons you might want to keep using
           | find:
           | 
           | - fd can't do everything find can. fd is intended to replace
           | the most common use cases with a simpler interface, but there
           | are many less common cases that require finds greater
           | flexibility. In fact, I still use find sometimes because of
           | this.
           | 
           | - find is more likely to already be installed
        
         | mellosouls wrote:
         | For anything I can't remember, I just use at the command line:
         | 
         | ? toolname <option>
         | 
         | Eg
         | 
         | ? git branch
         | 
         | which gives me common examples of git branch
         | 
         | It aliases to tldr which is normally up to date with new tools.
         | 
         | See also cheat.sh etc.
         | 
         | https://tldr.sh/
         | 
         | I understand the point about muscle memory but I think that was
         | more of a concern in the days before we had it easy with
         | instant internet answers and now LLMs (eg GitHub copilot
         | command line) doing our boring thinking for us.
        
         | eulers_secret wrote:
         | Another reason to at least learn the default tooling is that
         | often I find myself SSHing to another machine which has only
         | the barest of default packages installed (often busybox,
         | sometimes just a stripped-down docker container).
         | 
         | If I didn't know how to use "find" and "grep" (though I prefer
         | rg) then I'd be at a disadvantage in these situations. Also
         | command-line git.
         | 
         | It's why I learned to use Vim well, though I daily Emacs.
        
         | thesuperbigfrog wrote:
         | >> For me, anything that isn't a drop-in replacement for the OG
         | tools isn't worth the friction.
         | 
         | "The uutils project reimplements ubiquitous command line
         | utilities in Rust. Our goal is to modernize the utils, while
         | retaining full compatibility with the existing utilities. We
         | are planning to replace all essential Linux tools."
         | 
         | https://uutils.github.io/
         | 
         | uutils is being adopted in Ubuntu 25.10:
         | 
         | https://www.theregister.com/2025/03/19/ubuntu_2510_rust/
        
           | rednafi wrote:
           | I welcome this wholeheartedly. If Ubuntu adopts that and it
           | doesn't need me to deal with any incompatibility, then it's a
           | win-win for everyone.
        
           | consp wrote:
           | With the added "benefit" of not having to use GPL. Likely the
           | main goal.
        
             | thayne wrote:
             | Why would that matter to Ubuntu?
        
           | d0mine wrote:
           | Does it mean unless your ip is considered "friendly", you
           | can't use basic computer utils? Gnu utils seem more
           | accessible (more freedom long term).
        
         | nrvn wrote:
         | It resonates with me wrt muscle memory and ubiquity of
         | "standard tools" that come pre-installed in majority of *nix
         | distros including macos.
         | 
         | But there is a big BUT! Lately I have to use grep/find huge
         | nested dirs and found rg to be an order of magnitude faster.
         | Had to get myself comfortable with retraining the muscle
         | memory. Worth the effort.
         | 
         | Some of these new shiny tools are meh for my taste. Delta for
         | instance. Or helix the editor. But it is personal. Overall I
         | love the competition. It seems like industry once full of
         | innovators and tinkerers is lacking some shake up.
        
       | Babkock wrote:
       | One of those essential tools, that's not ever included with
       | GNU/Linux by default, but I always install almost immediately
       | along with ripgrep, bat, fzf, htop.
        
         | meonkeys wrote:
         | Agreed! Curious what your base OS is. Mine has been Ubuntu LTS
         | for years, but now I find myself installing so many custom
         | tools like these I'm thinking I might want to move to NixOS or
         | Gentoo or something like that instead. I just don't want to
         | lose out on stability and great hardware support.
        
           | carlhjerpe wrote:
           | Hey!
           | 
           | I would recommend trying home-manager, or just plain nix
           | profiles before going all-in on NixOS, it's very easy to add
           | Nix on top of any Linux (and MacOS to an extent).
           | 
           | This way you still have your tried and true base system and
           | you can manage things somewhat like you're used to (and use
           | venv and whatever bullshit package manager everyone invents),
           | a lot of common tools will work poorly on NixOS (venv,
           | npm...)and while they have Nix alternatives that are "better"
           | it's DIFFERENT.
           | 
           | I run NixOS on desktop and laptop but I wouldn't recommend
           | starting with it, you can benefit from all packages on any
           | distro by just installing Nix.
           | 
           | Also home-manager adoption can be incremental.
           | 
           | ADHD end note: home-manager is perfect for CLI tools
           | installation and config. You must unconfigure "secure path"
           | in sudo though otherwise your CLI tools don't work with sudo
        
         | thibran wrote:
         | I would add 'ouch' to the list. It allows easy compression/de-
         | compression.
        
           | drcongo wrote:
           | And procs - https://github.com/dalance/procs
        
         | creeble wrote:
         | For the sake of Ubuntu users, it's 'apt install fd-find'.
         | You'll need an alias fd=fdfind too.
        
         | kristopolous wrote:
         | try ugrep https://github.com/Genivia/ugrep ... if you don't
         | switch over in a day, I'll eat my shoe.
         | 
         | It supports all the common grep options and you can split view
         | in the -Q mode and it is smart enough to open your $editor at
         | the line number it's talking about.
         | 
         | Try it, this is the workflow I've been waiting for.
         | 
         | Also lf. https://github.com/gokcehan/lf You've been wanting
         | this for years as well.
         | 
         | No really. Just scroll:
         | https://github.com/gokcehan/lf/wiki/Integrations ...
         | https://github.com/chmouel/zsh-select-with-lf these things will
         | change your life. I promise.
        
           | kstrauser wrote:
           | Whoa! Thankgs for mentioning lf. That's beautiful!
        
             | amelius wrote:
             | I'm on bash, and now I'm jealous :(
             | 
             | By the way, this reminds me of the Norton Commander days
             | ...
        
               | kristopolous wrote:
               | bash bind and zsh bindkey are similar enough that you can
               | probably just llm convert it to bash.
               | 
               | curl https://raw.githubusercontent.com/chmouel/zsh-
               | select-with-lf... | llm -x "Convert this zsh script to
               | bash" > maybe-bash.sh
               | 
               | seems to work for me.
        
               | kstrauser wrote:
               | I'm on Fish and the integrations don't work as-is for me
               | either. However, the tool itself is quite slick!
        
           | ac29 wrote:
           | > Also lf. https://github.com/gokcehan/lf You've been wanting
           | this for years as well.
           | 
           | Check out yazi, its the nicest TUI file manager I have used:
           | https://yazi-rs.github.io/
        
       | HeadlessChild wrote:
       | This saved me a ton of time when I had to migrate id ownership of
       | files in ancient NFS shares.
       | 
       | [0] https://news.ycombinator.com/item?id=31489004
        
       | alkh wrote:
       | Imo, everyone should check https://terminaltrove.com/ from time
       | to time. There, I have found easy replacements to commonly used
       | tools:
       | 
       | find -> fd, time(for runtime comparison) -> hyperfine,
       | grep->ripgrep, asciinema + converting to .gif -> t-rec[1],
       | manually creating convertional commits -> koji[2], etc.
       | 
       | [1]https://terminaltrove.com/t-rec/
       | [2]https://terminaltrove.com/koji/
        
         | johnisgood wrote:
         | koji would be fine, but I want to stick to 67 column width and
         | I could not do it with this, I think? I use git-cola, instead.
        
           | alkh wrote:
           | yeah, that's a problem for me as well. I end up doing
           | koji->gitlint->git commit --amend --edit if there are any
           | width issues
        
         | imoreno wrote:
         | Instead of koji, I use `aider --commit`
        
         | tmtvl wrote:
         | Would be nice if you could filter based on license. I really
         | want to avoid non-(A)GPL tools where possible.
        
       | enricozb wrote:
       | I wish fd and rg would align some of their flags. For example,
       | both fd and rg have a --type, but for fd it means
       | file/directory/symlink etc. For rg it means the file MIME type.
       | Another example is that fd has an --extension flag, and rg
       | doesn't.
       | 
       | Since I believe the correlation of usage of these tools is high,
       | I think they could benefit from having similarly named flags.
        
         | hnlmorg wrote:
         | To be honest, this is one of the reasons I usually stick with
         | POSIX tools, I'm too old and too lazy to want to learn a whole
         | new set of flags for a whole new set of tools that are very
         | close to but not quite the same as what's already part of my
         | muscle memory now.
         | 
         | Not taking anything away from the tools that have been written.
         | Just for me, the pain of learning a new tool is greater than
         | the convenience I'd gain from using it.
        
           | renewiltord wrote:
           | It's actually because they stayed compatible that the problem
           | arises: fd and find -type mean the same but this user wants
           | them to be different.
           | 
           | Overall, I use AI shell completion so it's much smoother.
        
             | hnlmorg wrote:
             | I've been thinking of adding AI completion into my CLI
             | tools but not really sure how to implement it in a non-
             | intrusive way. So I've got a few questions, if you don't
             | mind sharing:
             | 
             | What's the workflow like for AI shell completion?
             | 
             | How does it know which flag to complete for you? Do you
             | write a description in native language (eg English) and it
             | completes the entire command line? Or is it more one flag
             | at a time?
        
               | renewiltord wrote:
               | Ah I do it from the other side
               | 
               | Got it from here
               | 
               | https://x.com/arjie/status/1575201117595926530?s=46
        
               | hnlmorg wrote:
               | Interesting. Thanks for sharing.
               | 
               | That gives me some ideas to try myself.
        
               | renewiltord wrote:
               | Good luck. Do share if any are sticky!
        
           | burntsushi wrote:
           | As the author of ripgrep, I find this unconvincing
           | personally. Have you ever tried to use `sed` with its `-i`
           | flag?
           | 
           | That's because `-i`, while incredibly useful, is not POSIX.
           | So when you say "POSIX tools," what you actually probably
           | mean is, "superset of POSIX tools."
           | 
           | There is some agreement among the same tools as what the
           | options in the superset actually mean, but not always, as is
           | the case with `sed`.
           | 
           | Compare, for example, what `man grep` says on your system
           | with the POSIX definition: https://pubs.opengroup.org/onlinep
           | ubs/9699919799/utilities/g...
           | 
           | As for whether flags are consistent across different tools,
           | well that's a total crapshoot. `find` uses `-L` for following
           | symlinks while `grep` uses `-R`. Ironically, both `fd` and
           | ripgrep use `-L`, so they are _more_ consistent than the
           | relevant superset-plus-POSIX tooling on at least that front.
           | 
           | To be clear, I mean this somewhat narrowly. Namely
           | 
           | > I'm too old and too lazy
           | 
           | I totally get that. I have a bunch of things I kinda want to
           | learn and do, but just not enough time in the day. But I do
           | still try to make time for these things. I did it for `tmux`
           | (previously, `screen`) and `zsh` (previously, `bash`) and I
           | am very happy I did. Each one cost me about a Sunday and a
           | half, but they've been paying rewards ever since.
        
             | ziml77 wrote:
             | I'm happy you gave ripgrep an option to perform
             | replacements so I don't have to worry about sed and its
             | lack of a standard way to change files in-place. I realize
             | on my Mac I could install GNU sed, but if I'm going to
             | install an extra utility anyway, why not go with something
             | that is overall nicer?
        
               | burntsushi wrote:
               | Hah, well, hate to break it to you, but ripgrep never
               | writes files, only reads them. So its `-r/--replace`
               | option only controls ripgrep's output, but doesn't
               | actually replace data inside a file.
        
               | ziml77 wrote:
               | I could swear I used it to do just that a handful of
               | times in the past. But my brain's been a bit scrambled
               | recently so I'm probably misremembering now. I know for
               | sure I made use of the replace option and was happy it
               | was there and that using it felt better than using sed.
               | 
               | I guess it does make sense now that I think about it that
               | ripgrep wouldn't do in-place edits. If ripgrep never
               | performs writes, there's never a chance of a mistake in
               | usage or bug in the software clobbering files in bulk.
        
               | robenkleene wrote:
               | I maintain a pair of tools that can do in-place file
               | replacements on ripgrep output
               | (https://github.com/robenkleene/rep-grep) and rename
               | files based on `fd` output
               | (https://github.com/robenkleene/ren-find).
        
               | burntsushi wrote:
               | > If ripgrep never performs writes, there's never a
               | chance of a mistake in usage or bug in the software
               | clobbering files in bulk.
               | 
               | Yeah that's exactly why it doesn't.
               | 
               | It is true that the `-r/--replace` flag can replace a
               | number of `sed` and `awk` use cases. It has for me at
               | least.
        
             | hnlmorg wrote:
             | > As the author of ripgrep, I find this unconvincing
             | personally. Have you ever tried to use `sed` with its `-i`
             | flag?
             | 
             | I have. But that's one inconsistency and an edge case I
             | rarely need to worry about.
             | 
             | Plus we are talking about grep here, not sed. I created my
             | own "sed" because I got fed up with dealing different
             | implementations of existing seds. If others use it or don't
             | use it then that's their choice, not mine.
             | 
             | > As for whether flags are consistent across different
             | tools, well that's a total crapshoot. `find` uses `-L` for
             | following symlinks while `grep` uses `-R`. Ironically, both
             | `fd` and ripgrep use `-L`, so they are more consistent than
             | the relevant superset-plus-POSIX tooling on at least that
             | front.
             | 
             | UNIX tools are a mess too. My point wasn't that their flags
             | are more sane than modern tools. It's that I've already
             | committed to memory the flags for the tools I use daily.
             | 
             | > Each one cost me about a Sunday and a half, but they've
             | been paying rewards ever since
             | 
             | I spend my free time writing open source tools that solve
             | problems I run into (like fixing the limitations with
             | existing UNIX shells, and presently writing a new terminal
             | emulator with a ton of features existing ones neglect). So
             | I don't have time to learn new tools to solve problems I
             | don't have.
             | 
             | Edit:
             | 
             | I just want add to my previous comment that some of my open
             | source tools do make use of your fantastic Go libraries,
             | such as the Unicode width library.
             | 
             | So I've really valued your contributions to open source
             | even though I don't personally use ripgrep specifically.
        
               | burntsushi wrote:
               | I mean that seems pretty reasonable? I find your
               | philosophy a little disappointing, but you do you. But it
               | is reasonable. I think you ignored this part of my
               | comment:                   > To be clear, I mean this
               | somewhat narrowly. Namely         >         >> I'm too
               | old and too lazy         >         > I totally get that.
        
               | hnlmorg wrote:
               | Not disappointing. Just pragmatic.
               | 
               | I have two young children plus maintain several open
               | source projects (like yourself) and a full time job too.
               | 
               | Time isn't infinite so I focus my energy on the stuff
               | that makes the biggest impact.
               | 
               | It's not like I'm ungrateful for your contributions to
               | open source and if you'd look at some of the stuff I've
               | been building you'd see we are pretty like minded with
               | regards to modernising the command line.
        
               | burntsushi wrote:
               | Oh, no, definitely disappointing! At least to me it is. I
               | totally believe in learning new things for the sake of
               | it, because it sometimes leads to serendipitously good
               | things. Otherwise it's really easy to end up in local
               | optima. Without that philosophy, I would have never built
               | ripgrep.
               | 
               | I'm not trying to convince you to do that. I already told
               | you that your philosophy is reasonable. But I absolutely
               | find it disappointing.
               | 
               | Anyway, yes, I have a kid. And all sorts of other things
               | competing for my time. So I don't get much time to do
               | serendipitous learning. But I try when I can. I cited two
               | examples, but that's over a period of many years. I don't
               | have time to do it often.
               | 
               | > you'd see we are pretty like minded with regards to
               | modernising the command line
               | 
               | I bet we are. Maybe you are a lot more open to learning
               | new things than you are letting on in your comments here.
               | :-)
        
               | hnlmorg wrote:
               | If you're willing to commit time to learning my shell
               | then I'm willing to commit time to learning ripgrep. ;-)
               | 
               | https://murex.rocks
               | 
               | Edit:
               | 
               | > I bet we are. Maybe you are a lot more open to learning
               | new things than you are letting on in your comments here.
               | 
               | Oh absolutely I'm open to learning new things.
               | 
               | Just recently I've been learning about tmux control mode
               | (eg what iTerm2 uses for tmux integration) because I
               | wanted to bypass tmux terminal emulation for specific
               | escape codes, meaning I can then draw native elements
               | inside a terminal window, such as spreadsheets, images,
               | and code folding, while still having full tmux
               | capabilities.
               | 
               | That was a "fun" ride. I plan on writing a blog about it
               | at some point because there's some features about tmux
               | that I think others would be surprised to learn.
        
               | burntsushi wrote:
               | Oh man that's nowhere near fair! ripgrep is one tiny
               | little command that is _mostly_ compatible with GNU grep.
               | Lots of the flags are the same. And its default usage is
               | really easy: `rg whatever`.
               | 
               | But I gave it ten minutes and ported part of https://gith
               | ub.com/BurntSushi/dotfiles/blob/bedf3598f2501ad5... to ht
               | tps://github.com/BurntSushi/dotfiles/blob/bedf3598f2501ad
               | 5...
               | 
               | Not much, but it took me some time to get the basics
               | down.
               | 
               | One thing that stood out to me was that startup times are
               | kinda brutal. I'm not sure if that's intended or if it's
               | something about my environment:                   $ cat
               | /tmp/murex-test         #!/usr/bin/murex
               | echo $ARGV         $ time /tmp/murex-test         [
               | "/usr/bin/murex",             "/tmp/murex-test"         ]
               | real    0.437         user    0.491         sys     0.110
               | maxmem  106 MB         faults  0              $ murex
               | --version         murex v6.4.2063 (develop)         GPL
               | v2         2018-2025 Laurence Morgan
               | 
               | That would probably be a deal breaker for me.
               | 
               | I got murex through the AUR:
               | https://aur.archlinux.org/packages/murex
               | 
               | > Oh absolutely I'm open to learning new things.
               | 
               | Okay then I'd say this is high contrast with your
               | comments above!
        
               | hnlmorg wrote:
               | Yeah I've not spent time optimising start up because it's
               | main emphasis is the interactive shell.
               | 
               | I guess you could liken it to Powershell or JVM in that
               | the start up is generally a one time cost if you're using
               | it interactively.
               | 
               | I could certainly invest a little time on the start up
               | though. It wouldn't be impossible to improve things
               | there.
               | 
               | > Okay then I'd say this is high contrast with your
               | comments above!
               | 
               | Is it though? I didn't say I'm adverse to learning new
               | things. Just that I don't want to learn replacements for
               | the tools I've already memorised.
               | 
               | But anyway, you've downloaded murex so I'll give ripgrep
               | go. I'm sure it'll become a staple tool for me now I've
               | committed time to it :)
        
               | burntsushi wrote:
               | Yeah I started with the shell script route because it
               | felt like the best way to get familiar with it quickly.
               | Then I'd probably go backwards to interactive usage.
               | 
               | The error messages did look very nice.
               | 
               | I have been considering dipping my toes into a less
               | standard shell over the past few years. It is so so so
               | hard to break away from the ubiquitous bullshit that most
               | of us are stuck with. I have no love for the Bourne shell
               | and its derivatives, although zsh is some nice lipstick
               | on a very ugly pig.
               | 
               | The other candidates I'm aware of are fish, nushell and
               | oils. I think nushell is the "most" different, but the
               | last time I tried it, I bounced off of it for reasons I
               | can't remember.
        
               | hnlmorg wrote:
               | Yeah, switching shell is a major time investment. I
               | couldn't blame you for sticking with the default, after
               | all, I was initially unwilling to invest time into
               | learning ripgrep :D
               | 
               | And you're right that it wasn't a fair a trade asking you
               | to look at Murex in exchange for ripgrep (which is nice
               | by the way!) but I respect that you did take a look
               | nonetheless.
        
               | jrockway wrote:
               | Yeah, I think your explanation is pretty reasonable. I am
               | also old and lazy and still find time to try new tools.
               | 
               | I am not sure I have ever gotten traditional "find" to do
               | what I want on the first try, and I've had a lot of first
               | tries. At some point you have to ask yourself, if I
               | haven't achieved zen in X years with Y tool, maybe the
               | problem is the tool and not me?
        
               | alwillis wrote:
               | I'm old and lazy too, which is why I use eza, bat and
               | other new tools that were created this century.
               | 
               | Why are we acting like we're still in the 80's and can
               | only use tools that existed then?
        
             | thiht wrote:
             | sed has to be one of the worst POSIX tools. It sounds
             | simple enough, but everytime I reach for sed it doesn't do
             | what I want, either because it doesn't align with how I do
             | things, or because it just doesn't support doing it
             | (especially multiline replacements for example).
             | 
             | I've switched to sd[1] because it basically just works as I
             | expect every time.
             | 
             | [1]: https://github.com/chmln/sd
        
           | sweeter wrote:
           | this is what tab completion and tldr is for. 99% of use cases
           | are well covered and clear by the name of the flag, and a
           | good CLI tool will make that easy to understand. A quick
           | example and self-explanatory flags with tab-completion is all
           | you need. Then if you ever have a more complicated use case,
           | you can grep through the man page.
           | 
           | its legit as simple as "fd -e png -x optimize-png {}" the
           | only thing I dont like about fd is that for some reason it
           | kind of forces you to do 'fd . Downloads' if you just want
           | everything in "Downloads" which equates to 'fd {pattern} Dir1
           | dir2" I wish you could omit the pattern sometimes.
        
           | ForTheKidz wrote:
           | ripgrep solves a really annoying part of the unix toolbox:
           | inconsistency in how to correctly search a bunch of files for
           | a string. Are you supposed to `find -name -exec`? Or are you
           | supposed to `find -name | xargs -n 1`? Oh, but files can have
           | spaces, so you might try `find -name -print0 | xargs`, but
           | careful--`-print0` is not POSIX and you won't find it on some
           | unixen! (let's not even discuss locate vs slocate vs
           | mlocate.... ugh! Files are worse than everything but all the
           | other options.)
        
         | derriz wrote:
         | Yeah this annoys me even though I'm a daily user of both fd and
         | rg. What makes it more confusing is that many of the flags DO
         | align - or partially align.
         | 
         | For example, I'm used to glob patterns but the glob flag (-g)
         | works differently in fd and rg. I think that fd's -g flag does
         | not use "full-path" globbing while rg's -g does (or the other
         | way around). To get fd to use rg style globs, it also needs the
         | -p flag, which rg also recognizes but it has a completely
         | different meaning for rg and has nothing to do with how
         | globbing/filename matching works.
         | 
         | I guess I'm used to the warts at this stage, like I had gotten
         | used to the warts on find and grep all those years ago.
         | 
         | Difficult or impossible to fix these inconsistencies at this
         | stage without breaking backward compatibility.
        
         | laktak wrote:
         | I used sql instead of flags to make it easier to remember - see
         | https://github.com/laktak/zfind
        
         | thayne wrote:
         | It's a tricky balance. To use your --type example, it isn't
         | consistent with rg, but it is mostly consistent with find. And
         | fd'a --type option is much more useful for fd than an
         | equivalent would be for rg. It doesn't make a lot of sense to
         | filter the files to grep to directories, or sockets, but that
         | is useful if you are searching for file names, or even just all
         | files of a certain type. Conversely, rg's --type option isn't
         | quite as useful for fd, because fd is already matching a
         | pattern against the file name, so you can easily just add the
         | appropriate extension to your search pattern. Or use the
         | --exyension flag.
        
       | puffybuf wrote:
       | fzf, ripgrep are some command line tools I like. Check them out.
       | Being able to quickly search your history with fuzzy finder is so
       | useful.
        
       | usrbinbash wrote:
       | There are many completely unnecessary "reworks" of classic UNIX
       | stdutils that add very little to no value, and instead pitch
       | themselves purely on "written in {lang-the-dev-likes}" or being
       | "blazing fast" or something similar.
       | 
       | `fd` isn't one of those.
       | 
       | `fd` is amazing.
       | 
       | It is simpler, faster and easier to grok than `find`, the
       | commands syntax is a straight up improvement, it comes with sane
       | defaults which makes the easy things and common usecases simple,
       | while the harder ones are way more accessible. It uses colored
       | output in an actually useful way, its manpage is more structured
       | and easier to read...
       | 
       | and MOST IMPORTANTLY
       | 
       | ...it is capable of running commands on search results with
       | _parallel execution out of the box_ , so no need to get GNU
       | parallel into the command.
       | 
       | THIS is the kind of renewal of classic command line utilitis we
       | need!
       | 
       | Literally the _only_ pain point for me, is that it doesn 't use
       | glob-patterns by default, and that is easily fixed by a handy
       | alias gf="fd -g"
        
         | beej71 wrote:
         | This is an honest question, not a criticism, but how much does
         | parallelism help? Isn't the disk a choke point?
        
           | kstrauser wrote:
           | Depends greatly on the use case. If you're finding all the
           | gifs in a directory and converting them to pngs, it may be
           | the case that CPU is hammered harder than IO. There are
           | surely counterexamples, too.
           | 
           | It's a nice option to have when you need it.
        
           | swiftcoder wrote:
           | A lot of developer machines are running expensive NVME SSDs,
           | which perform well enough the disk isn't so much of a choke
           | point. If you run on spinning rust, YMMV
        
           | usrbinbash wrote:
           | Theoretically yes, practically not really (any more). NVMe
           | cards are fast enough that a single core traversing the file
           | system can actually be a chokepoint, so parallelisation helps
           | a lot here.
           | 
           | I also should have made it clear that my comment also wasn't
           | so much about the _search_ (although the parallel search is
           | absolutely a nice-to-have)...it was about the `-x, --exec`
           | being automatically in parallel.
           | 
           | A common usecase is to find all files of X criteria, and then
           | perform the same operation on all of them, e.g. find all
           | session logs older than N days and then compress them, or
           | convert all wav files in a directory tree to mp3
           | 
           | If the operation is computationally expensive, using more
           | than one core speeds things up considerably. With `find`, the
           | way to do that was by piping the output to GNU parallel.
           | 
           | With `fd` I can just use `-x, --exec` and it automatically
           | spins up threads to handle the operations, unless instructed
           | not to.
        
       | pimlottc wrote:
       | For folks on macOS, you can also use "mdfind" as a command-line
       | interface for macOS Spotlight search
       | 
       | https://ss64.com/mac/mdfind.html
        
         | kstrauser wrote:
         | I never remember what it's called, so I have `alias locate
         | 'mdfind -name'` in my shell setup.
        
           | pimlottc wrote:
           | If it helps you remember, it appears that the "md" in
           | "mdfind" stands for "metadata" [0]
           | 
           | 0: https://en.wikipedia.org/wiki/Spotlight_(Apple)#macOS
        
             | kstrauser wrote:
             | Yeah, for some reason my brain's incapable of pinning that
             | in cache.
             | 
             | Oh well, that's what they invented aliases for in the first
             | place.
        
         | spudlyo wrote:
         | Considering how many as many CPU cycles and iops that Spotlight
         | robs from you on a regular basis, you might as well get some
         | use out of it.
        
       | BeetleB wrote:
       | I never managed to use find. I would always find a different way
       | to solve my problem (e.g. Midnight Commander).
       | 
       | I use fd all the time.
       | 
       | Simply having a better command line interface is a big deal.
        
       | ilyagr wrote:
       | I got used to https://github.com/tavianator/bfs instead. Breath-
       | first ordering is nice.
       | 
       | Interestingly, the author is listed as one of the maintainers of
       | `fd` as well.
        
       | singhrac wrote:
       | I use fd all the time. I admit it, I couldn't get the muscle
       | memory right for find. One day I'll be on a bare Linux
       | installation where I can't cargo install whatever I want and I'll
       | have to ask ChatGPT to generate my find commands.
       | 
       | I like `fd -o {user}` and `fd --newer {time}` to find recently
       | changed files and owned by others.
        
       | derefr wrote:
       | I was just thinking yesterday that I'd appreciate a more modern
       | alternative to find(1). Not a simplified one, though!
       | 
       | The original problem that led me to thinking about this, was that
       | I wanted to do a search that would include all files below the
       | current directory, _except_ if they were within a specific
       | subdirectory.
       | 
       | (Why not just `grep -v` for that directory? Because the subdir
       | contained millions of files -- in part, I was trying to avoid the
       | time it would take find(1) just to do all the system calls
       | required to list the directory!)
       | 
       | And yes, this is possible to specify in find(1). But no, it's not
       | ergonomic:                   find . -path ./excluded_dir -prune
       | -o -type f -print
       | 
       | You can add parentheses, if you like. (But you don't have to. It
       | seems find(1) has implicit Pratt parsing going on):
       | find . \( -path ./excluded_dir -prune \) -o \( -type f -print \)
       | 
       | This incantation entirely changed my perspective on find(1) as a
       | tool. Until I learned this, I had never understood exactly why
       | find(1) nags you to put its arguments in a specific order.
       | 
       | But this makes "what find(1) does under the covers" very clear:
       | it's assembling your expression into a little _program_ that it
       | executes in the context of each dirent it encounters on its
       | depth-first traversal. This program has filtering instructions,
       | like `-path`, and side-effect instructions, like `-print`. You
       | can chain as many of each as you like, and nest them arbitrarily
       | within (implicit or explicit) logical operators.
       | 
       | After some further experimentation, I learned that find's
       | programs are _expression_ -based; that every _expression_
       | implicitly evaluates to either true or false; and that any false
       | return-value anywhere in a sub-expression, is short-circuiting
       | for the rest of that sub-expression. (You could think of every
       | instruction as being chained together with an implicit  &&.) This
       | means that this won't print anything:                   find .
       | -false -print
       | 
       | In other words, my original expression above:
       | find . -path ./excluded_dir -prune -o -type f -print
       | 
       | ...is actually this, when translated to a C-like syntax:
       | (path("./excluded_dir") && prune()) || (type("f") && print())
       | 
       | As soon as I realized this, I suddenly became very annoyed with
       | find(1)'s actual syntax. Why is find(1) demanding that I write in
       | this weird syntax with leading dashes, various backslash-escaped
       | brackets, etc? Why can't I "script" find(1) on the command-line,
       | the same way I'd "script" Ruby or Perl on the command-line? Or
       | heck, given that this whole thing is an expression -- why not
       | Lisp?                   find '(or (and (path "./excluded_dir")
       | prune) (and (type f) print))'
       | 
       | I do _understand_ why find(1) was designed the way it was -- it
       | 's to allow for shell variable interpolation, and to rely on
       | shell argument tokenization.
       | 
       | But it's pretty easy to work around this need -- just push both
       | of these concerns "to the edge" (i.e. outside the expression
       | itself. Like SQL statement binding!)
       | 
       | * Support $VAR syntax for plain references to exported env-vars.
       | 
       | * Support positional binding syntax (?1 ?2 ?3) for positional
       | arguments passed after the script.
       | 
       | * Support named binding syntax (?foo) for positional arguments
       | after the script that match the pattern of a variable-assignment
       | (ala make(1) arguments):                   find '(or (and (path
       | ?excluded_dir) prune) (and (type f) (iname ?1) print))' foo
       | excluded_dir="${bar[1]}"
       | 
       | I don't know about you, but I _personally_ find this grammar 10x
       | easier to remember than what find(1) itself has going on.
        
         | tavianator wrote:
         | You might be interested in rawhide[1] or fselect[2]. (Note: I
         | don't really use them myself, but they seem to offer something
         | like what you're suggesting.)
         | 
         | Also, this is still a find-style syntax, but my bfs utility
         | supports -exclude [3]. So you can write                   bfs
         | -type f -exclude -path ./excluded_dir
         | 
         | which is a bit more ergonomic.
         | 
         | [1]: https://github.com/raforg/rawhide
         | 
         | [2]: https://github.com/jhspetersson/fselect
         | 
         | [3]:
         | https://github.com/tavianator/bfs/blob/main/docs/USAGE.md#-e...
        
       | linza wrote:
       | I find these tools super awesome, but i never use them beyond
       | trying them out once, because they don't usually come with
       | coreutils or something like that.
       | 
       | Haven't found a way to use these tools in a user-local way.
       | 
       | For my own homemade tools, i put the binary in my dotfiles and
       | they end up in .local/bin and i can use them by default. I can do
       | that because I don't need to update them.
        
       | theflyinghorse wrote:
       | After using nushell for a few month it's really hard for me to go
       | back to the old ways. A million of different tools all with
       | different API and outputs are just not the way to go
        
       | greggh wrote:
       | Every new install gets zsh, kitty, exa, fzf, bat, ripgrep, fd,
       | neovim, ducker, qman, cht.sh, navi, and hyperfine as the first
       | things I do.
        
         | metaltyphoon wrote:
         | zsh, fzf, bat, rg, fd, neovim, tldr, lazygit, jq, yazi,
         | starship, hyperfine, ghostty.
        
           | helsinki wrote:
           | Now we're talking.
        
       | Tomte wrote:
       | > fd is distributed under the terms of both the MIT License and
       | the Apache License 2.0.
       | 
       | So not dual-licensed (MIT OR Apache-2.0), but MIT AND Apache-2.0?
       | That's unusual.
       | 
       | Later: it seems they intended dual-licensing, and botched the
       | wording: https://github.com/sharkdp/fd/issues/105
        
       | coldtea wrote:
       | Amazing program. Along with rg great QOL improvements
        
       | terminaltrove wrote:
       | if you want to try fd, bat, numbat, hexyl and hyperfine, you can
       | install them quickly and see screenshots of them below on
       | Terminal Trove:
       | 
       | fd - https://terminaltrove.com/fd/
       | 
       | bat - https://terminaltrove.com/bat/
       | 
       | numbat - https://terminaltrove.com/numbat/
       | 
       | hyperfine - https://terminaltrove.com/hyperfine/
       | 
       | hexyl - https://terminaltrove.com/hexyl/
       | 
       | we make a real effort to ensure that you can install them with
       | the ability to see the screenshots.
        
         | jwrallie wrote:
         | Nice suggestions, I'll be definitely trying numbat and
         | hyperfine (I already use fd daily).
         | 
         | I could see bat being useful only as the last program on a long
         | pipe chain, but I really like xxd so I will pass on hexyl.
        
         | andy_xor_andrew wrote:
         | cool site, have you considered using asciicinema instead of
         | screenshots? Seems like the perfect tool for what you're trying
         | to do
         | 
         | https://asciinema.org/
        
         | d0mine wrote:
         | Perhaps something like https://github.com/xtermjs/xterm.js can
         | be used to show interactive sessions for TUI apps.
        
         | nchmy wrote:
         | I look forward to exploring the tools some more. Though, I
         | install everything these days via mise (which you list as
         | well).
         | 
         | Would be cool if you had mise commands - be it just
         | 
         | mise use -g fd
         | 
         | or for other tools that arent in their registry, how to use the
         | backends like
         | 
         | mise use -g cargo:xyztool
        
       | mrobot wrote:
       | Has anyone made an awk replacement? I find awk get's really
       | annoying and ugly really fast, as things become even mildly
       | complicated.
       | 
       | I feel like awk could be so much better.
        
         | TylerE wrote:
         | For me anything beyond the most trivial one liner I just write
         | in python or whatever.
         | 
         | Maintainability >>>>>>> terseness.
         | 
         | It's not 1976 where every cycle matters.
        
       | zie wrote:
       | I honestly never use find anymore, I just use ripgrep(rg). rg is
       | so fast, that I don't worry about the ridiculously extra overhead
       | of searching content. I can't remember the last time I used find.
        
       | luckman212 wrote:
       | I just released an Alfred workflow[0] for searching a group of
       | user-defined directories, that heavily relies on fd under the
       | hood. Thank you @sharkdp for this amazing tool, I use it every
       | day and it is wonderful.
       | 
       | Hyperfine is another underrated gem that is just so great.
       | 
       | [0] https://github.com/luckman212/alfred-pathfind/
        
       | foresto wrote:
       | fd is also a file & directory maintenance command by Shirai
       | Takashi. (Package name: fdclone) I think it has been around for
       | at least couple of decades.
        
       | keithnz wrote:
       | On windows, for those that don't know, use Everything from
       | https://www.voidtools.com/
       | 
       | This is a VERY fast file searching tool. It's crazy good.
        
       | nout wrote:
       | My favorite way is to just have this in my zsh aliases.
       | # Find file by prefix (ignore case).        # Usage: 'f' or 'f
       | myfile' or 'f myfile.txt \etc'        # or f '*css'
       | function f() {         find ${2:-.} -iname "${1}*" 2>/dev/null |
       | grep '^\|[^/]*$'       }            # We use noglob, so zsh
       | doesn't expand characters like "*"        # and so we can do e.g.
       | f *css       alias f='noglob f'
        
       | anacrolix wrote:
       | I like it but the defaults are super annoying. I'm always trying
       | to find things I can't otherwise but it defaults to ignoring git
       | dirs and dot files, literally the thing I search for the most
        
       | DrNosferatu wrote:
       | No flatpak / snap for latest version and automated upgrades?
        
       | chinabot wrote:
       | Works really well for me. tks
        
       | kiitos wrote:
       | COMMAND                                 OUTPUT    WALLCLOCK_SEC
       | USR_SEC    SYS_SEC         time find ~ -iregex '.*\.jpg$' | wc -l
       | 14372             45.04        4.59      13.23         time find
       | ~ -iregex '.*\.jpg$' | wc -l  14372             48.42        4.60
       | 13.59         time find ~ -iname '*.jpg' | wc -l      14372
       | 44.55        1.07      13.57         time find ~ -iname '*.jpg' |
       | wc -l      14372             44.94        1.08      13.64
       | time fd '.*\.jpg$' ~ | wc -l            14325              4.01
       | 2.67      24.16         time fd '.*\.jpg$' ~ | wc -l
       | 14325              4.37        2.73      30.28         time fd -g
       | '*.jpg' ~ | wc -l            14325              3.98        2.72
       | 25.84         time fd -g '*.jpg' ~ | wc -l            14325
       | 4.04        2.69      26.82
       | 
       | Good to use concurrency, predictable impact on all of the various
       | timings. Different results vs. find for the same term (assumedly)
       | are unexpected? Did I mess up the translations?
        
       ___________________________________________________________________
       (page generated 2025-03-20 23:02 UTC)