[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)