5

I'm looking for a better find. The reason is that the find user interface is unintuitive to me (in particular, the pruning / -print style) and difficult to wrap in a function due to strict requirements on argument ordering. locate / updatedb isn't flexible enough to use instead. Would anyone care to share their example find wrappers or find alternatives (command line only, please)?

Here's an example of what I find to be unintuitive usage:

find dir_a dir_b \( -path dir_a/.git -o -path dir_b/out \) -prune -o \( -type f -o -type l \)

Specifying directories before options is strange to me and the syntax for pruning is easily forgotten. (Some programs use a --exclude option instead.) I recognize this is a picky point.

Here's my best attempt at specifying some defaults without losing much functionality:

f()
{
  # The trouble is that -regextype must appear after path but before expression.
  # HACK: "-D debugopts" unsupported and -[HLPO] options assumed to before dirs.
  local a=()
  while [[ -n "$1" ]] && ( [[ ! "${1:0:1}" =~ [-!(),] ]] || [[ "${1:0:2}" =~ -[HLPO] ]] )
  do
    a+=("$1")

    # Eliminate arg from @.
    shift
  done

  find -O3 "${a[@]}" -nowarn -regextype egrep "$@"
}

It seems silly to require a perfect understanding of all options in the program to be able to wrap it up with some defaults and not lose functionality / compatibility with plain find.

I'm guessing I won't fine anything as standard as GNU find, but there might be something better, albeit lesser known.

Update (2013-11-26):

  • At Itay's suggestion, I used ack for about a year. It works very well for at least 95% of my searches.
  • I recently discovered Ag, which is a fast version of ack. It's been working well for the past few weeks.

Update (2014-11-23):

I highly recommend Ag. It works great. There are still many times Find is necessary and for that I continue to seek a nice replacement. Although unquestionably useful, Find's interface is very dated and unnecessarily difficult in my opinion.

Update (2017-08-04):

I now most highly recommend ripgrep as an indispensable Ag replacement. It's a very new tool but it's support for .gitignore files greatly surpasses Ag and in all other ways it is equivalent or better. I continue to search for a Find replacement.

Update (2021-11-28):

I continue to use and love ripgrep which meets most of my needs. For everything else, I use a mixture of find and fd.

Stephen Niedzielski
  • 2,497
  • 1
  • 28
  • 34
  • 1
    The _strict requirements on argument ordering_ are not very clear, since you invoke `find` with `-O3` which may evaluate the tests in a different order. – C2H5OH May 25 '12 at 00:37
  • Xargs with Find is somewhat usefull but I use File::Find from Perl. – starbolin May 25 '12 at 00:42
  • @C2H5OH, when I mentioned strict ordering, I meant that which is imposed by find itself. If the ordering isn't as expected, find will error out. I recognize optimization may internally change ordering, but that's fine. – Stephen Niedzielski May 25 '12 at 00:52
  • @starbolin, do you normally invoke from the command line? I tagged the post with bash to hint that I'm looking for options available from the shell. I've updated the original post to make this clear. – Stephen Niedzielski May 25 '12 at 00:54
  • 8
    Please give an example where `find` does not work for you. I don't see the point of trying to replace a properly working, standard, well know GNU util with something adhoc. – Ankur Agarwal May 25 '12 at 20:28
  • @abc, there is no such example. find works for me but I seek an alternative that is easier to use and easier to script. I've my question to provide greater clarity. – Stephen Niedzielski May 25 '12 at 21:49
  • It's really hard to imagine how could `locate` not be flexible enough, considering that you can process its output with sed, AWK, Perl/Python/Ruby or even shell scripting. – C2H5OH May 25 '12 at 22:43
  • 1
    @C2H5OH, locate is actually quite primitive compared to find in every way except indexing. Locate doesn't maintain a lot of key file attributes such as type, timestamps, permissions, and owner. find also has a lot of really nice functions to operate on files that locate would require an additional xargs sh invocation and a fair amount of scripting to support. I'm seeking a find replacement, not seeking to write one :) – Stephen Niedzielski May 25 '12 at 23:51
  • +1 At the beginning, I think _Why do you need other tools, when there is find_. But I recognized immediately that `find` is not very user friendly, when condition is complex. – Lenik Jul 24 '12 at 09:34
  • 3
    When conditions are complex, conditions are complex. Within the set of *good* tools you will find tools that handles a specific subset of complex conditions well and simply, and tools that are flexible, but require configuration and understanding of the complexity. You cannot have your cake and eat it too. – kojiro Jul 26 '12 at 13:52
  • Why not just write a wrapper around find? – helpermethod Nov 26 '13 at 16:36
  • @helpermethod, as mentioned in the question, it's quite difficult to wrap in a function due to strict requirements on argument ordering. – Stephen Niedzielski Nov 26 '13 at 16:49

1 Answers1

2

You should try Ack, which is a replacement for both find and grep, optimized for working with source-code trees.

Itay Perl
  • 12,844
  • 3
  • 18
  • 12