5

On Mac OS X or Linux, is there a simpler form of the command

find . -name "*substring_of_filename*"

which is to find all files having names containing substring_of_filename within the current directory (or some other given directory). Because it's a common thing to do, is there a way to make the command shorter and easier to type, possibly using an alias or function in Bash? Or is there some other easy-to-type command that can be used?

Such as:

findfile . substring_of_filename

(Note: The question as originally written used app_config as an example of substring_of_filename.)

2
  • 2
    locate app_config
    – knittl
    May 2, 2011 at 15:00
  • 1
    @knittl: But locate is not restricted to the current dir and it's subdirs. Nov 10, 2012 at 5:25

10 Answers 10

5

On Mac OS X you may also put an alias using mdfind into .bashrc:

# mdfind uses Spotlight 
alias findf='mdfind -onlyin . -name'

findf app_config
3

Here's your bash function, put it in .bashrc:

function findfiles { find "$1" -iname "*$2*"; }

(Note that -iname makes the search case-insensitive. If you don't want that, use -name instead.)

2
  • You can also run this in a bash session if you want to use it just for the current session.
    – Wuffers
    May 7, 2011 at 1:19
  • iname is not equivalent, name is. It might be your favorite usage, but was not the question. Nov 10, 2012 at 5:27
2

Au contraire! There is an even more complicated one, but one, which works:

find . -name "*app_config*"

The dot isn't neccessary for gnu-find:

find -name "*app_config*"

But you have to mask the asterixs, else they will be interpreted by the shell, and you will only find filenames which match the ones in the current directory, which match "app_config".

7
  • seems not true at least on Mac OS X
    – Ruler Theodore
    May 2, 2011 at 15:23
  • What seems not true? That you can omit the dot? Or that a file which contains 'app_config' in its name and which is in the current directory, will restrict the search to his name. May 2, 2011 at 15:51
  • I mean on Mac OS X, you can use find . -name *app_config* without the quotes
    – Ruler Theodore
    May 2, 2011 at 15:57
  • 1
    @BenU: I don't have a System with Mac OS X, but on Linux, the need for quotes arises from the shell. If I don't quote the "*", the shell tries to expand it. It is not needed needed for find, and not, if the * doesn't match something in the current dir - then it is passed unchanged to find. You may try single quotes, which are allowed too in bash, but would prevent variable expansion (which isn't the case, here, but sometimes else) -name "*.pdf.$id" for example. Nov 10, 2012 at 5:13
  • 1
    For the record, quotes should be used in OS X just the same way as in Linux, since OS X has the same Bash shell as Linux. Mar 28, 2013 at 11:56
1

Put this either in your ~/.profile or ~/.bashrc, not sure which one Mac uses:

findname () 
{ 
    find . -name "*$1*"
}

then call the function by findname name_of_file

if you wanted to use multiple words, you'd have to get more complicated..the easiest way I can think of offhand is this:

findname() 
{ 
    find .|grep $1|grep $2|grep $3|grep $4 
}

That will find every file in your current dir, search for string 1, then search that result for string 2, and etc, till it gets to 4.

1
  • The second function doesn't work unless the variables are quoted like find . |grep "$1" |grep "$2" |grep "$3" |grep "$4". Also, it searches for parts of the path rather than parts of filenames. Mar 28, 2013 at 13:12
0

Instead of doing this in a bash, zsh, tcsh, sh, etc... script I made a TextExpander shortcut. I type sh≤Space≥ and TE types

find . -iname "**"

and puts the cursor between the asterisks.

0

On OS X, Why not just use locate? Granted the locatedb isn't updated very often by default, but you can change that easily (change the periodic job scheduling on OS X). locate is a BSDism, don't know if it's on Linux or not.

1
  • In some scenarios locatedb is a security risk. LUKS-encrypted home directory + not encrypted root + updatedb indexing /home and storing its cache somewhere in /var (which is not encrypted) leaks filenames from /home.
    – vtest
    May 7, 2011 at 22:53
0

On most Linux distributions, you can use locate. For example:

$ locate find | grep bin
/sbin/findfs
/usr/bin/find
/usr/bin/find2perl
/usr/bin/findsmb
/usr/bin/gst-typefind-0.10
/usr/bin/memdiskfind
/usr/bin/oldfind
/usr/bin/sane-find-scanner
/usr/include/c++/4.5/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp
/usr/include/c++/4.5/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp
/usr/include/c++/4.5/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp
0

If you use bash 4 (with shopt -s globstar) or zsh:

prinftf %s\\n **/*substring_of_filename*
0

The answer is "no". There is no shorthand for "find file by filename with substring in current directory or below" in GNU find. The aliases I use to work around this limitation are as follows (for zsh):

# find file in cwd by [S]ubstring, case [I]nsensitive, change to first sub[D]irectory
finds()   { find .  -name "*$**"; }
findsi()  { find . -iname "*$**"; }
findsid() { cd `find . -iname "*$**" | head -n1 | xargs dirname`; }

The last one is my favorite. These can be used as follows:

> ls -R
.:
file1  File2  HOLEFILE  test

./test:
hello

(that's the test directory)

> findsi file
./HOLEFILE
./File2
./file1

> finds file
./file1

> finds le
./File2
./file1

> findsid ell
> ls
hello
1
  • If anyone ports these to their shell of choice, feel free to edit this post and add your version. Apr 24, 2013 at 9:42
-1

I think just grep can do it fine, no need for find. Relevant options from the manpage:

 -l, --files-with-matches
          Suppress  normal  output;  instead  print the name of each input
          file from which output would normally have  been  printed.   The
          scanning  will  stop  on  the  first match.  (-l is specified by
          POSIX.)

 -H, --with-filename
          Print  the  file  name for each match.  This is the default when
          there is more than one file to search.

 -R, -r, --recursive
          Read all  files  under  each  directory,  recursively;  this  is
          equivalent to the -d recurse option.

Note that even if -H is the default when there's more than one file to search, I still suggest you to use it explicitly. This switch solves a particular problem of yours, it's better to remember this bit of directly related knowledge than the edge case (searching multiple files) when this option is the default.

So the grep version of your original find command will look like this:

grep -lHR app_config .
1
  • 2
    I suspect "all files having the app_config in it" really meant "all files having app_config in their names".
    – Eroen
    Mar 5, 2012 at 1:56

You must log in to answer this question.