others-Introduction to some tricks of linux `find` command

1. Purpose

In this post, I would introduce some tricks of linux find command ,which is used frequently in common linux operations. I would show some examples and explain why it works.

Without further ado, let’s dive in.

2. The introduction of linux find command

Say there is a directory named showfind with the following subdirectories and files:

➜  showfind tree -F .
.
├── a.txt
├── d1/
│   └── d11/
│       ├── d111/
│       └── d112/
│           └── b.txt
└── d2/
    └── c.txt

5 directories, 3 files
➜  showfind

2.1 How to do the file search job recursively by using ‘find’ command?

If you want find all the files named *.txt in all subdirectories recursively, Just do as follows:

➜  showfind find . -name "*.txt"
./d1/d11/d112/b.txt
./a.txt
./d2/c.txt

➜  showfind
  • The first option . means to find files from within the current directory
  • The -name "*.txt" option means to find all files that suffixed with .txt , don’t forget to enclose the pattern in quotes in order to protect it from expansion by the shell
  • by default, the search is recursive

So the format to find specified files recusively is as follows:

find <directory> -name "<THE_PATTERN>"

Replace the and with real values.

For detailed -name option explanation:

       -name pattern
              Base of file name (the path with the leading directories
              removed) matches shell pattern pattern.  
              
              Because the
              leading directories are removed, the file names considered
              for a match with -name will never include a slash, so
              `-name a/b' will never match anything (you probably need
              to use -path instead). A warning is issued if you try to
              do this, unless the environment variable POSIXLY_CORRECT
              is set.  
              
              The metacharacters (`*', `?', and `[]') match a
              `.' at the start of the base name (this is a change in
              findutils-4.2.2; see section STANDARDS CONFORMANCE below).
              To ignore a directory and the files under it, use -prune
              rather than checking every file in the tree; see an
              example in the description of that action.  Braces are not
              recognised as being special, despite the fact that some
              shells including Bash imbue braces with a special meaning
              in shell patterns.  Don't
              forget to enclose the pattern in quotes in order to
              protect it from expansion by the shell.

2.2 How to do the file search job only in current directory(not recursively) by using ‘find’ command?

If you just want to fine specified files in current directory, Just do as follows:

➜  showfind find . -name "*.txt" -maxdepth 1
./a.txt

➜  showfind

Here we added a new option -maxdepth, here is the explanation:

 -maxdepth levels
              Descend at most levels (a non-negative integer) levels of
              directories below the starting-points.  Using -maxdepth 1
              means only apply the tests and actions to the current directory

2.3 How to find with regex patterns?

If you want to find files that match certain regex patterns, you can do as follows:

➜  showfind find . -regex ".*c\..*"
./d2/c.txt

➜  showfind

2.4 How to find files with multiple conditions?

If you want to find files with two or more conditions, just do as follows:

➜  showfind find . -name "*.txt" -name "c.*"
./d2/c.txt

2.5 How to find files by file size ?

We can use the option -size to find files by its size :

-size n[cwbkMG]
              File uses less than, more than or exactly n units of
              space, rounding up.  The following suffixes can be used:

              `b'    for 512-byte blocks (this is the default if no
                     suffix is used)

              `c'    for bytes

              `w'    for two-byte words

              `k'    for kibibytes (KiB, units of 1024 bytes)

              `M'    for mebibytes (MiB, units of 1024 * 1024 = 1048576
                     bytes)

              `G'    for gibibytes (GiB, units of 1024 * 1024 * 1024 =
                     1073741824 bytes)

              The size is simply the st_size member of the struct stat
              populated by the lstat (or stat) system call, rounded up
              as shown above.  In other words, it's consistent with the
              result you get for ls -l.  Bear in mind that the `%k' and
              `%b' format specifiers of -printf handle sparse files
              differently.  The `b' suffix always denotes 512-byte
              blocks and never 1024-byte blocks, which is different to
              the behaviour of -ls.

              The + and - prefixes signify greater than and less than,
              as usual; i.e., an exact size of n units does not match.
              Bear in mind that the size is rounded up to the next unit.
              Therefore -size -1M is not equivalent to -size -1048576c.
              The former only matches empty files, the latter matches
              files from 0 to 1,048,575 bytes.

For example, there is a large file in the directory:

➜  showfind tree -F .
.
├── a.txt
├── d1/
│   └── d11/
│       ├── d111/
│       └── d112/
│           └── b.txt
└── d2/
    ├── Grammarly.dmg
    └── c.txt

5 directories, 4 files


➜  showfind ls -l d2/Grammarly.dmg
[email protected] 1 bswen  staff  18655910 Dec 12 20:56 d2/Grammarly.dmg
➜  showfind

The file Grammarly.dmg is about 18M, now we use find with option -size to find it:

➜  showfind find . -size +1M
./d2/Grammarly.dmg

2.6 How to find files and then action on those files?

Normally , we find some files and action on them, e.g. list them or delete them.

For instance, if we want to find the large file and delete them , we can do as follows:

➜  showfind find . -name "*.txt" -exec ls -l {} \;
-rw-r--r--  1 bswen  staff  0 Dec 12 20:34 ./d1/d11/d112/b.txt
-rw-r--r--  1 bswen  staff  0 Dec 12 20:34 ./a.txt
-rw-r--r--  1 bswen  staff  0 Dec 12 20:34 ./d2/c.txt

➜  showfind

The format is:

find <options> -exec COMMAND {} \;

3. Summary

In this post, I demonstrated how to use find command to find specified files by its name pattern or size . That’s it, thanks for your reading.