30

Is there an alternative find program with a more conventional CLI interface? find works and expects parameters in a painfully different way from most other utils.

Clarification: I'm looking for a program that has mostly the same functionality as find with a commandline interface that works and feels like POSIX (or at least GNU) commandline recommendations.

closed as primarily opinion-based by Kiwy, Kusalananda, Jeff Schaller, Satō Katsura, GAD3R May 9 '17 at 14:24

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 6
    GNU find does not respect POSIX (or even GNU) guidelines for command line. For example, ordering of parameters, multi-character options with a single dash etc. are different than in conforming programs. – Tamás Szelei May 20 '11 at 11:11
  • 3
    I know, and I can always do what I intend, one way or another. I just recently got to know ack and was wondering if there is a better find as well. – Tamás Szelei May 20 '11 at 11:40
  • 2
    No. You see, I don't want a small programming language, but a simpler, more intuitive and more consistent find (even if that means the loss of some advanced functionality). When I face a task that justifies writing a program, I do. – Tamás Szelei May 20 '11 at 14:28
  • 2
    find is both consistent (see my answer) and intuitive. It's not like primaries are named weird. -exec means execute, -print means print it, -name means match a name. In practice, the former 3 and -type cover 95% of the usage cases. For all other cases, there's man find. – Mel May 20 '11 at 16:27
  • 3
    @tamas I edited an hour ago and told you there's no alternative except locate. And maybe ls -R come to think of it. Other alternatives are GUI programs that emulate find. Otherwise you have to specify what you want your find alternative to do. Walk dir trees? Filter file names? Tell you which files is newer then? – Mel May 20 '11 at 17:24
11

This is a common misconception.

Find follows the options syntax. You're just confusing expression primaries with options:

 find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
 [cmd][-->        options          <--] [--> arg0..argN  <--]

The alternative is locate. But find implements its own expression syntax because it provides a richer set of filter and action options. There's no alternative that can do the same, simply because it would be redundant.

  • 4
    Even if it's my fault, this does not answer my question. – Tamás Szelei May 20 '11 at 14:29
  • What is the difference between expression (only one allowed?), cmd (dito?), options and args? – user unknown May 20 '11 at 15:35
  • @user unknown -- the find command implements it's own expression syntax. The expression, when given, is the last argument on the command line. When absent, expression resolves to -print. – Mel May 20 '11 at 16:03
  • Ah - now I see, [cmd] isn't following [expression], but it's a description of the line before. – user unknown May 21 '11 at 3:04
  • 2
    OP asserts that find "expects parameters in a painfully different way from most other utils". You state that OP is "confusing expression primaries with options". Do most other utils even have a concept of "expression primaries"? If not, doesn't that demonstrate OP's point? And that's really not the strangest part of using find. What other CLI involves {} (which of course must be escaped somehow)? – Kyle Strand Aug 24 '17 at 16:39
10

It depends on the precise functionality of find that you are relying on. If it is (principally) the finding functionality, some shells support recursive globs. E.g., with zsh:

% find . -name \*c
./a/b/foo.c
./a/bar.c
./baz.c
inoshiro% ls *.c
baz.c
% ls **/*.c 
a/bar.c  a/b/foo.c  baz.c

Zsh has a lot more find-like possibilities through glob qualifiers (look near the end of man zshexpn). For example:

ls -l **/*(.)  ≈  find -type f -ls
ls *(m-2u:$USER:)  ≈  find -mtime -2 -user $USER

Bash 4 also has **/ (you need to enable it with shopt -s globstar), but nothing like glob qualifiers.

10

I would take a look at locate. It will look through its database of files and quickly print out path names that match what you give.

kevin@box:~$ locate odg
/home/kevin/Documents/final.odg
/usr/share/doc/packages/sysconfig/netconfig.odg
/usr/share/gimp/2.0/help/en/gimp-tool-dodge-burn.html
....
kevin@box:~$ locate .odg
/home/kevin/Documents/final.odg
/usr/share/doc/packages/sysconfig/netconfig.odg
kevin@box:~$ 

As you can see, it is a sub-text match: if you give it odg, then it will match dodge. But if you give it .odg, then it won't.

There is one downside, though: it needs a database. This database needs to be updated when things change. My Fedora 13 install has this put into a daily crontab, though.

  • I love locate – Andrew Lambert May 21 '11 at 10:00
  • 1
    Moreover, locate also accepts patterns (I learned this just recently). – Adam Byrtek May 21 '11 at 17:55
5

What are you trying to find? If you're typically searching for source code files, take a look at ack. It's basically a source code search tool, but ack's -f switch will find files that match a given filetype.

So if you want to find all the Perl files in a directory, for example, just:

ack -f --perl

If you don't like the filetypes that ack recognizes, you can add your own in your ~/.ackrc.

ack is not a general-purpose file finder like find, but if you're working with source code, it can be very handy.

  • 1
    This is not what user asked but people might find very useful for find in source code (like grep) The Silver Searcher, silversearcher-ag package on main distros. – Pablo Bianchi Jul 12 '17 at 22:20
-1

One of the great things every programmer should learn is: If you can't find a tool, build your own!

#!/usr/bin/bash
find -name $<

I might write a better one, with -t to filter types, etc.

Edit: The above is a Bash script. It takes the command line argument and passes it to find as the -name option's value. Just a simple example. Since I put up this answer, I found this python script:

https://github.com/sjl/friendly-find/

The interface looks nice, but I haven't tested its performance. Might be worth checking out.

  • 1
    True for building own tool statement. But at least explain how your little script is supposed to work. – jippie Dec 16 '12 at 9:27
  • 1
    $< is not doing anything useful in my Bash. What do you expect it to do? Do you mean "$@" actually? Or "$1" (which is basically what this means in a Makefile)? – tripleee May 9 '17 at 7:21
  • 1
    @tripleee - $< is the csh equivalent of read - I'm guessing he meant that. – DarkHeart May 9 '17 at 13:40
-2

Most standard way to find things in unix's.

du -a <directory>|grep <pattern>| awk  '{print $2}'
  • 1
    grep | awk is an antipattern. See useless use of grep. If you want to parametrize the pattern, maybe du -a | awk -v "pat=<pattern>" '$0 ~ pat { print $2 }' – tripleee May 9 '17 at 7:24
  • @tripleee That's very helpful info about awk, but one of the great advantages of the UNIX philosophy is that one doesn't need to understand all the features of the more complex tools (such as awk and find) in order to construct pipelines that can perform the desired task. grep | awk may not be optimal (or, on a performant multithreaded system with a highly optimized grep, maybe it would be!), but it's simple. – Kyle Strand Aug 24 '17 at 16:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.