find
If the GUI search tool (I hear this from Mac users) is not doing what you want, you can try using the command line. The find
command can do very many things, some quite complicated. For our purposes, we just want to use it to search for files in a tree of directories. find
will search all directories that are within a specified directory.
Here is a suggested procedure.
(1) Open a terminal – this is left as an exercise for the reader.
(2) Type pwd
at the prompt (I will use $ to represent the prompt) and hit Enter. pwd
tells you where you are now in the file tree. For example, if I do it now on my computer, I get this:
$ pwd /cygdrive/h/MyDocs
You will get something different.
(3) Use the cd
(change directory) command to move to the region of the file tree you want to search. For example, I can move to /home
and then check that I am there:
$ cd /home $ pwd /home
(4) Now, you can search for the files. The form of a find command is:
$ find <directory> <flag> <pattern>
We have fixed the <directory> part by cd
ing to where we want to search. On the command line ‘.’ means ‘current directory’. We want to find files by name, so we use the ‑name
flag, and then our search text. So:
$ find . -name zmc
will find all files in the current file tree that are called ‘zmc’, and show me their paths (it turns out there are none). It will not find ‘ZMC’, ‘Zmc’, ‘zmcd’ etc. It will find an exact match. If I want ‘ZMC’ I search for ‘ZMC’ not ‘zmc’.
(5) Let's say we wanted to search for InDesign files. That is, files whose names end in (lower case) ‘indd’. We run:
$ find . -name "*indd"
(Note the double quotes – this is a good habit). The ‘*’ means ‘anything’, so this will find all files that end in ‘indd’. For example, if I change my ‘zmc’ search to ‘zmc*’ I get more results:
$ find . -name "zmc*" ./username/installs/ZMC/ZMC_toolbox_source_April_2016/zmc_Nov03_2015.f90 ./username/installs/ZMC/ZMC_toolbox_source_April_2016/zmc_subroutines.mod
(6) I can specify more detail to narrow my search. For example:
$ find . -name "zmc*mod" ./username/installs/ZMC/ZMC_toolbox_source_April_2016/zmc_subroutines.mod
So now I have found files starting with ‘zmc’ and ending in ‘mod’.
(7) A '?' stands for any 1 character, so for example:
$ find . -name "fr?d" ./frad ./fred ./frod
The leading ‘./’ means they are in my current directory – the one I cd
ed into.
The ‘?’ demands a character.
$ find . -name "fr?d?"
finds nothing because none of the file names has a fifth character. On the other hand, ‘*’ matches any number of characters, including none:
$ find . -name "fr?d*" ./username/fred.icn ./frad ./fred ./frod
(8) I can use as many ‘?’ as I like:
$ find . -name "?r?d" ./username/installs/julia/julia/doc/deps/registries/General/G/Grid ./frad ./fred ./frod
All of ‘Grid’, ‘fred’, ‘frad’ and ‘frod’ match the pattern. ‘????’ would match all four-character file names. Similarly:
$ find . -name "fr?d????" ./username/fred.icn
The four ‘?’ match ‘.icn’ but nothing else.
(9) I can change the flag ‘-name
’ to ‘-iname
’ where you can think of the ‘i’ as meaning 'insensitive'. This is not a search done by a man, but one that is case insensitive. So I can repeat an earlier search but with this flag:
$ find . -iname "zmc*" ./username/bin/ZMC ./username/installs/ZMC ./username/installs/ZMC/ZMC_toolbox_source_April_2016 ./username/installs/ZMC/ZMC_toolbox_source_April_2016/ZMCLinux_gfort_stat ./username/installs/ZMC/ZMC_toolbox_source_April_2016/ZMCLinux_gfort_stat_32bit (etc etc etc!)
Note that find also matches paths (that is, directory names). ‘./username/installs/ZMC
’ is a directory.
(10) You can replace the ‘.’ in the find
command with the path to the directory you want to search, rather than cd
ing into the directory. For example:
$ find /home -iname "*.docx"
This will find anything within /home
ending in ‘.docx’, ‘.DOCX’, ‘.dOCx’, ‘DoCx’, etc.
(11) If you get too many results, you can deal with this in several ways. Making the search more specific is one. One is by adding ‘| more’ to the end of your command (‘|’ is the vertical bar character, called a pipe):
$ find /home -iname "*.docx" | more
You can pipe the output of find through the grep
command. It will pick out results that match another criterion.
$ find /home -iname "*.docx" | grep -i "draft"
(again, ‘i’ means insensitive). This will find results that have ‘.docx’ on the end and ‘draft’ somewhere else. This is handy because you can use it to select based on directory rather than file name. It would find files ending in ‘.docx’ that have ‘draft’ in the name of the file and/or in the name of the path.