

ffind: a sane replacement for command line file search - molbon
http://wrongsideofmemphis.com/2012/11/19/ffind-a-sane-replacement-for-command-line-file-search/

======
silentbicycle
I wrote a similar tool to this in C, ff
([https://github.com/silentbicycle/ff](https://github.com/silentbicycle/ff)).

The main difference is that, where `ffind foo` appears to be comparable to

    
    
        find . -name "*foo*"
    

, ff is closer to

    
    
        find . -name ".*f.*o.*o.*"
    

In other words, you don't need an exact match, just the characters given in
order. (This is inspired by Lisp-y toolchains where e.g. c-w-c-c would search
and expand to call-with-current-continuation.)

There are some other features (e.g. '=' toggles literal match, it has smart
handling for '/' and directory name grouping), but it's pretty straightforward
to use. It also doesn't depend on python.

------
msluyter
Similarly, I have a little shell function loaded by .zshrc that covers 90% of
my use cases:

    
    
       findit() {
           find . -name \* -exec grep -iH $1 {} \;
       }

~~~
knome
Why not just run a recursive grep? That would save having to invoke grep on
every single file found.

    
    
        findit() {
            grep -iHR $1 .
        }
    

Alternately, you could use the '+' variant of -exec in order to batch files
together to be processed together.

~~~
msluyter
Cool, I wasn't aware of a -R flag in grep for some reason. I need to go back
and re-read the man pages...

------
saidajigumi
Many of the commenters here have missed an essential line of ffind's
description from the article, emphasis mine:

> find in this directory and all the subdirectories a file that contains
> some_text _in its filename_

This is NOT a find+grep/ack/ag -alike. It's used for rapid search on
filenames, not file contents. Think of it as TextMate's Cmd-T for the command-
line.

------
mwfunk
I find myself doing this a lot when sifting through huge codebases:

find . -type f -print0 | xargs -0 grep -Hin <identifier>

The -print0/xargs thing is to get around spaces in filenames or directories. I
don't think spaces belong in source files (or directory trees containing
source code) for a gazillion different reasons, but I still stumble across it
every once in a great while. There are also platforms where system directories
have spaces in them, so if you're scrounging through a deep subdirectory tree
trying to find something, you may have to deal with the spaces thing. I've
been bitten by it enough times that I just always do this rather than have to
think about whether or not I might need to do it every time I use find.

Depending on what I'm looking for, I might select files with -type, or a -name
glob, or whatever. I use '-type f' most commonly because the source code I
deal with has a fair number of interesting things defined outside of files
with the standard source/header extensions in their names.

There's usually a couple pipe stages after this filled with 'grep -v <stuff I
don't care about>', or more greps to narrow down the result set. Sometimes
this all goes in shell scripts or sometimes I just type it all out.

~~~
psutor
How about

    
    
      grep -irn <identifier> .

?

-r recurses and since it is multiple files implies -H.

~~~
mwfunk
Yep, that's much nicer. :) I always forget about recursive grep.

------
b0rsuk
Alternatively, you may just install _locate_. It won't examine file contents,
but it works in the common cases. It's also blazingly fast because it's
indexed.

~~~
resiros
Its problem that you always have to update the index, which can be problematic
in fast changing systems (and quite slow in some cases). The greatest
disadvantage is that you need root rights to update the index.

~~~
cnvogel
You can have arbitrary indices being created by arbitrary users. The
database(s) that is(are) used by the locate command can be specified by
command-line option or by an environment variable.

------
sciurus
If you just want a shortcut to invoke find in this common way, put this in
your shell's profile:

    
    
      function ffind {
          if [ $# -eq 1 ]; then
              search_path='.'
              expression=$1
          elif [ $# -eq 2 ]; then
              search_path=$1
              expression=$2
          else
              echo "ffind [path] expression"
              return 1
          fi
          find $search_path -name $expression
    }

------
resiros
I looked into his python implementation, I thought he would just translate the
parameters and call find, but he instead did go to implement the search
algorithm. Wouldn't that make it a bit slower than the original find?

~~~
frontfor
File system traversal can be quite slow on traditional hard disk drive, it
requires a lot of random disk access which has much higher latency than
sequential access (think about the moving parts in the disk drive). So I guess
that being written in Python is hardly the bottleneck if the disk reads have
not been cached by the kernel.

------
revscat
What are the advantages of this over

    
    
        mdfind -onlyin . <str>

~~~
hollerith
It searches the contents of files, not just the names of files.

~~~
revscat
So does mdfind.

~~~
hollerith
I stand corrected.

(I tested before I posted, but forgot MD indexing was turned off.)

------
dreen
Yeah thats ok but holy cow, thanks for letting me find out about ack! ack is
awesome!

~~~
thezilch
If you like ack (and who doesn't???), you might like more or less `ag`:
[https://github.com/ggreer/the_silver_searcher](https://github.com/ggreer/the_silver_searcher)

~~~
dreen
I did notice ack is pretty slow and i may try ag but speed isnt a problem here
for me i think

btw, heres what ive been using up until now:

    
    
        alias gerp='grep -riHnT . -e'
    

and more recently:

    
    
        alias gerp="find . -type f | perl -lne 'print if -T;' | xargs egrep -riHnT"

------
neurobashing
This ffind isn't this ffind: [https://github.com/sjl/friendly-
find](https://github.com/sjl/friendly-find) ?

------
gcv
In zsh:

    
    
        print -l **/*myfile

------
taeric
From reading this, I'm not entirely sure what makes this better than grep. I
get why it is cool to have written it.

~~~
calpaterson
It's not a replacement for grep, it's a replacement for find

~~~
taeric
That works by searching the contents of files. So, it is just a grep -l -R .
'search terms', right?

Edit: Actually, now that I am revisiting this thread. The top post hit my
misunderstanding on the head.

------
falsedan
It is a remarkable shame the author did not read the ack manpage to discover
the '-g' option.

------
anonymous
why not just find|grep <pattern>

------
nodata
find | grep foo

