Read

Module 4 · Finding things

find by name and type

Walking a whole directory tree to locate files by name, ignoring case if needed, and telling files from directories with -type.

What you will learn

  • Read `find`'s structure: starting points, tests, actions.
  • Search by name with `-name` and `-iname`, quoting the pattern.
  • Filter by `-type`, limit depth, and combine tests with `!` and `-o`.

grep searches *inside* files; find searches *for* files. It starts at one or more directories, walks down through every subdirectory, and for each entry it meets it evaluates a list of tests. Entries that pass all the tests get the action, which by default is simply printing the path. The general shape is find [WHERE...] [TESTS] [ACTION], and if you leave out *where*, it starts in the current directory.

~% cd /root/lab/l35
l35% find etc
etc
etc/app.conf
etc/conf.d
etc/conf.d/db.conf
etc/conf.d/net.conf
etc/backup.conf
etc/notes.conf.bak
l35% find etc -name '*.conf'
etc/app.conf
etc/conf.d/db.conf
etc/conf.d/net.conf
etc/backup.conf
l35% find etc -type f -name '*.conf'
etc/app.conf
etc/conf.d/db.conf
etc/conf.d/net.conf

Paths come out relative to where you told find to start: begin at etc and you get etc/..., begin at /root/lab/l35/etc and every line is absolute. The order is the order of the directory on disk, not alphabetical; pipe into sort if you need it sorted.

-name and its quotes

-name PATTERN compares the entry's name (not the whole path) with a wildcard pattern: the same *, ? and [...] from lesson 18, but this time find does the matching. So the pattern must reach find untouched, which means quoting it: find . -name '*.conf'. Without quotes, if the current directory happens to contain app.conf, the shell rewrites the command into find . -name app.conf and you silently get the wrong answer. -iname is the same test ignoring case, so -iname '*.jpg' also finds HOLIDAY.JPG.

-type and friends

TestTrue for
-type fregular files
-type ddirectories
-type lsymbolic links (also b, c, p, s from lesson 19)
-maxdepth Ndo not go more than N levels down (1 = only the start directory's contents)
-path PATTERNthe whole path matches, e.g. '*/conf.d/*'

Combining tests

Tests written one after another must all be true: -type f -name '*.conf' is "a file AND named *.conf". -o means OR: -name '*.jpg' -o -name '*.png'. ! negates the next test: ! -name '*.bak'. AND binds tighter than OR, so when you mix them, group with escaped parentheses: find . -type f \( -name '*.jpg' -o -name '*.png' \).

Commands in this lesson

CommandWhat it does
find DIRList everything under DIR, recursively.
find DIR -name '*.conf'Entries whose name matches the pattern.
find DIR -iname '*.jpg'The same, ignoring case.
find DIR -type fOnly regular files (`d` directories, `l` links).
find DIR -maxdepth 1Do not descend into subdirectories.
find DIR -name A -o -name BEither test (OR).
find DIR ! -name '*.bak'Negate a test.

Quiz

  1. What is the difference between `grep` and `find`?

    • None, they are aliases
    • `grep` searches inside files for lines; `find` searches the tree for files
    • `find` only works on the current directory
  2. Why should you write `find . -name '*.txt'` with quotes?

    • Otherwise the shell may expand `*.txt` before `find` sees it
    • `find` requires quotes around every argument
    • To make the search case-insensitive
  3. Which command lists only the directories under `/root/lab`?

    • `find /root/lab -type d`
    • `find /root/lab -name d`
    • `find /root/lab -dir`
  4. What does `-iname '*.jpg'` match that `-name '*.jpg'` does not?

    • Files inside subdirectories
    • `PHOTO.JPG` and other case variants
    • Hidden files
  5. `find . -maxdepth 1 -type f` lists…

    • The files directly in the current directory, not in subdirectories
    • The largest file
    • Only the first file found

Practice

  1. Under /root/lab/l35/etc there are configuration files at several depths. Save into /root/lab/l35/confs.txt the paths of all **regular files** whose name ends in `.conf` (one is a directory with a `.conf` name: leave it out).

  2. Several users under /root/lab/l35/home have a **directory** called `cache` somewhere in their tree; one user has a regular file called `cache` instead. Save the paths of the `cache` directories only into /root/lab/l35/caches.txt.

  3. The photos under /root/lab/l35/pics were saved by different cameras, so the extension is `.jpg`, `.JPG` or `.Jpg`. Save the paths of all of them into /root/lab/l35/jpgs.txt with one `find`.

Open this lesson in the app to do the tasks in a real Linux machine and have them checked.