The find command remains one of the most powerful Linux tools for locating files, but using it only to search by name means missing much of what it can do. It can filter by size, date, permissions, ownership, file type, or directory depth, detect broken symbolic links, and execute actions on the results. Used properly, it can handle everything from everyday searches to maintenance and security tasks without installing additional software.

The key points about the Linux find command in 30 seconds

  • find walks directory trees and can combine filters for name, type, size, time, user, or permissions.
  • Options such as -mtime, -mmin, -size, and -perm make highly precise searches possible.
  • -exec runs commands against matching files, while -delete can remove them directly.
  • Wildcards such as *.log should normally be protected with quotes.
  • Some options differ between GNU find on Linux and BSD implementations used by systems such as macOS.

The basic syntax is straightforward:

find PATH EXPRESSION

For example:

find /var/log -name "*.log"Code language: JavaScript (javascript)

The command starts at /var/log, walks through its subdirectories, and returns files and directories whose names end in .log.

But find becomes much more useful when understood as a small query language for the filesystem. Different conditions can be combined to answer questions such as “which files larger than 500 MB were modified during the last seven days?” or “which executables owned by this user have overly permissive permissions?”

Searching by name, type, and location

A dot . represents the current directory:

find . -name "config.php"Code language: JavaScript (javascript)

This searches for any object named exactly config.php.

To restrict the results to regular files, use -type f:

find . -type f -name "config.php"Code language: JavaScript (javascript)

The main file types are:

ExpressionSearches for
-type fRegular files
-type dDirectories
-type lSymbolic links
-type bBlock devices
-type cCharacter devices
-type pFIFOs or named pipes
-type sSockets

To find directories:

find . -type d -name "cache"Code language: JavaScript (javascript)

There is an important difference between -name and -iname.

find . -type f -name "*.jpg"Code language: JavaScript (javascript)

is case-sensitive.

It could therefore find:

photo.jpgCode language: CSS (css)

but not necessarily:

PHOTO.JPG
Photo.JPGCode language: CSS (css)

To ignore case:

find . -type f -iname "*.jpg"Code language: JavaScript (javascript)

Why "*.jpg" should normally be quoted

This small precaution prevents many mistakes:

find . -name "*.jpg"Code language: JavaScript (javascript)

If you write:

find . -name *.jpgCode language: CSS (css)

the shell itself may expand *.jpg before find receives the argument.

If the current directory contains several JPG files, the final command received by find may not be what the administrator intended.

That is why patterns are normally protected with single or double quotes:

find . -name '*.jpg'Code language: JavaScript (javascript)

How to find files by size

find can select files according to their size.

To find files larger than 100 MB:

find . -type f -size +100M

For smaller files:

find . -type f -size -10M

And to specify a range:

find . -type f -size +100M -size -500M

This is particularly useful when investigating systems that are running out of storage.

The main units available in GNU find include:

SuffixUnit
cBytes
k1,024-byte units
M1,048,576-byte units
G1,073,741,824-byte units

Therefore:

-size +1G

searches for objects above the threshold expressed in 1 GiB units, even though the option uses G.

A typical query for finding large storage consumers could be:

find /var -type f -size +1GCode language: JavaScript (javascript)

To display their sizes as well:

find /var -type f -size +1G -exec ls -lh {} +Code language: JavaScript (javascript)

Searching by date: mtime, ctime, and atime are not the same

This is one of the areas of find that causes the most confusion.

Linux maintains several timestamps related to a file.

OptionWhat it represents
-mtimeModification of file contents
-ctimeChange to metadata/inode
-atimeLast access
-mminModification measured in minutes
-cminMetadata change measured in minutes
-aminAccess measured in minutes

To search for files modified within roughly the last 24 hours:

find . -type f -mtime -1

To search for modifications during the last 60 minutes:

find . -type f -mmin -60

A useful example for system administrators is:

find /etc -type f -mmin -60

which can help identify configuration files modified recently.

ctime is not the creation date

A common mistake is interpreting:

-ctime

as creation time.

It does not mean that.

On traditional Unix systems, it means change time, referring to changes to inode metadata.

For example:

chmod 600 file

can change the ctime even though the contents of the file remain exactly the same.

To find files whose metadata has changed recently:

find . -type f -ctime -2

Searching between two specific dates

GNU find provides -newermt, which is convenient for setting time boundaries:

find . -type f -newermt "2026-09-01"Code language: JavaScript (javascript)

To specify a range:

find . -type f \
  -newermt "2026-09-01" \
  ! -newermt "2026-09-10"Code language: JavaScript (javascript)

This makes investigations much easier to read than manually converting dates into numbers of days.

Another file can also be used as the reference point:

find . -type f -newer reference.txtCode language: CSS (css)

This returns files newer than reference.txt.

Finding files by permissions and ownership

find is particularly useful for basic server audits.

To locate files with exactly 777 permissions:

find . -type f -perm 0777

Another form of -perm can be used to find files where particular permission bits are set.

For example, to locate files with the SUID bit:

find / -type f -perm -4000 2>/dev/nullCode language: JavaScript (javascript)

The Set User ID (SUID) bit allows certain executables to run with the privileges of their owner.

That does not mean every SUID file is dangerous. Legitimate system tools may require it, but knowing which ones exist is useful during a security audit.

To locate files executable by their owner:

find . -type f -perm -u+x

You can also search by user:

find /home -type f -user david

Or by group:

find /srv -type f -group www-data

Another useful query after deleting a user account is to find files whose owner no longer exists:

find / -nouser 2>/dev/nullCode language: JavaScript (javascript)

And for groups that no longer exist:

find / -nogroup 2>/dev/nullCode language: JavaScript (javascript)

Finding empty files and broken symbolic links

To find empty files:

find . -type f -emptyCode language: PHP (php)

To locate empty directories:

find . -type d -emptyCode language: PHP (php)

This can help when reviewing temporary directories, misconfigured applications, or abandoned directory structures.

Symbolic links can also be found easily:

find . -type l

But there is a difference between finding every symbolic link and finding only those whose targets no longer exist.

With GNU find:

find . -xtype l

is a common way to detect broken symbolic links.

An audit of /var/www could therefore use:

find /var/www -xtype lCode language: JavaScript (javascript)

The distinction matters because -type l by itself does not mean “broken symbolic link”. It returns symbolic links regardless of whether their targets still exist.

Controlling how deep find searches

By default, find searches recursively.

To examine only the current directory:

find . -maxdepth 1 -type f

For example:

find /etc -maxdepth 1 -type f

will not walk through /etc/nginx, /etc/ssh, and the other subdirectories.

There is also -mindepth:

find . -mindepth 2

which excludes objects in the initial levels.

Both options can be combined:

find /srv \
  -mindepth 2 \
  -maxdepth 4 \
  -type f

This is useful for particularly large directory trees where a complete recursive search would be unnecessary.

-exec: when find starts doing things with the results

Finding a file is often only the first step.

-exec allows another command to be executed against the results.

For example:

find . -type f -name "*.txt" -exec cat {} \;Code language: CSS (css)

Here {} represents each path found.

The terminator:

\;

causes the command to run separately for every result.

There is a usually more efficient alternative:

find . -type f -name "*.txt" -exec cat {} +Code language: CSS (css)

The + allows multiple filenames to be grouped together and passed to the program in batches when possible.

For example, to change permissions on all .txt files:

find . -type f -name "*.txt" -exec chmod 644 {} +Code language: CSS (css)

Or to search for the word ERROR inside log files:

find /var/log -type f -name "*.log" \
  -exec grep -H "ERROR" {} +Code language: JavaScript (javascript)

-exec and {} explained

The braces represent the name of the object found by find.

This command:

find . -type f -name "*.conf" \
  -exec ls -l {} \;Code language: CSS (css)

could conceptually result in:

ls -l ./app.conf
ls -l ./nginx/site.conf
ls -l ./backup/old.conf

With {} +, however, find tries to group them:

ls -l ./app.conf ./nginx/site.conf ./backup/old.conf

This can significantly reduce the number of processes created when there are thousands of results.

Moving files: be careful with a common syntax

To move all PNG files to /tmp, GNU systems can use:

find . -type f -name "*.png" \
  -exec mv -t /tmp -- {} +Code language: JavaScript (javascript)

That form depends on GNU mv.

A more portable alternative is:

find . -type f -name "*.png" \
  -exec mv {} /tmp/ \;Code language: JavaScript (javascript)

There is an important risk: if different directories contain files with identical names, moving all of them into the same destination can create conflicts.

Searching from . while the destination directory is itself inside the search tree can also produce behavior that should be considered beforehand.

-delete: powerful and dangerous

find can also delete files directly.

To remove .tmp files:

find . -type f -name "*.tmp" -deleteCode language: JavaScript (javascript)

Or empty directories:

find . -type d -empty -deleteCode language: JavaScript (javascript)

Broken links could also be removed:

find . -xtype l -deleteCode language: JavaScript (javascript)

But -delete deserves one simple rule:

always run exactly the same search without -delete first.

Before running:

find /srv -type f -name "*.tmp" -deleteCode language: JavaScript (javascript)

run:

find /srv -type f -name "*.tmp"Code language: JavaScript (javascript)

and carefully inspect the output.

There is no recycle bin between find and deletion. A badly constructed expression can remove thousands of files in seconds.

AND, OR, and NOT: combining conditions

When several conditions are written consecutively, find normally applies an implicit AND.

find . -type f -name "*.log" -size +100MCode language: JavaScript (javascript)

means:

regular file AND name ending in .log AND size greater than 100 MB.

For OR, use -o:

find . -type f \( -name "*.jpg" -o -name "*.png" \)Code language: JavaScript (javascript)

This searches for JPG or PNG files.

The parentheses are escaped so that the shell does not interpret them.

To negate a condition:

find . -type f ! -name "*.log"Code language: JavaScript (javascript)

This returns files that do not end in .log.

A more realistic example:

find /var/www \
  -type f \
  \( -name "*.php" -o -name "*.js" \) \
  -mtime -7Code language: JavaScript (javascript)

locates PHP or JavaScript files modified recently.

30 useful find examples

GoalCommand
Find a filefind . -type f -name "file.txt"
Find JPG filesfind . -type f -name "*.jpg"
Ignore casefind . -type f -iname "*.jpg"
Find directoriesfind . -type d -name "backup"
Empty filesfind . -type f -empty
Empty directoriesfind . -type d -empty
Larger than 100 MBfind . -type f -size +100M
Between 100 and 500 MBfind . -type f -size +100M -size -500M
Recently modifiedfind . -type f -mtime -1
Modified in 60 minutesfind . -type f -mmin -60
Accessed within an hourfind . -type f -amin -60
Metadata changedfind . -type f -ctime -2
Newer than another filefind . -type f -newer ref.txt
Modified since a datefind . -type f -newermt "2026-09-01"
Find by userfind . -type f -user david
Find by groupfind . -type f -group www-data
No valid userfind / -nouser
Exact 777 permissionsfind . -type f -perm 0777
Find SUID filesfind / -type f -perm -4000
Owner-executable filesfind . -type f -perm -u+x
Symbolic linksfind . -type l
Broken symbolic linksfind . -xtype l
Current level onlyfind . -maxdepth 1 -type f
Show detailsfind . -type f -exec ls -lh {} +
Search file contentsfind . -name "*.txt" -exec grep -H "ERROR" {} +
Change permissionsfind . -name "*.txt" -exec chmod 644 {} +
Delete .tmp filesfind . -type f -name "*.tmp" -delete
Delete empty directoriesfind . -type d -empty -delete
Find JPG or PNGfind . -type f \( -name "*.jpg" -o -name "*.png" \)
Exclude .gitfind . -path "./.git" -prune -o -type f -print

find vs. locate, fd, and grep

find is not the only tool available.

ToolWhere it excels
findPrecise filesystem searches
locateVery fast filename searches using an index
fdModern, convenient alternative for common searches
grepSearching for content inside files
ripgrep (rg)Very fast text searches, particularly in source code

locate can be extremely fast because it does not need to walk through the disk during every query, but its database may not include files created only a few minutes ago.

fd, available in many distributions although not normally installed by default, provides a simpler interface for many everyday searches.

For example:

fd '\.jpg$'Code language: JavaScript (javascript)

can be more convenient than building some equivalent find expressions.

However, when advanced conditions, permissions, ownership, timestamps, depth controls, command execution, or compatibility with minimal Linux servers are required, GNU find remains one of the fundamental tools in a system administrator’s toolbox.

It is also worth remembering that many examples found online are written specifically for GNU findutils, which is common on Linux. BSD find, used on systems such as macOS, shares much of the syntax but not every extension. Options such as -newermt and certain behaviors may require different approaches.

Learning find, therefore, is not about memorizing dozens of commands. The useful part is understanding its three building blocks: where to search, which conditions to apply, and what to do with the results. Once those concepts are clear, administrators can build queries far more useful than any fixed collection of examples.

Frequently Asked Questions

How do I find a file by name across the entire Linux system?

You can use find / -type f -name "file.txt", although searching the entire filesystem may require elevated permissions and can produce permission-denied messages.

How do I find the largest files with find?

To locate files larger than 1 GB, use find /path -type f -size +1G. It can then be combined with -exec ls -lh {} + to display their sizes.

What is the difference between -mtime and -ctime?

-mtime refers to modifications to file contents, while -ctime records changes to the file’s status or metadata. ctime does not mean creation time.

Is find -delete safe to use?

It can be used safely when the search criteria are correct, but the same command should first be run without -delete so the results can be reviewed. A mistake in the expression can cause large numbers of files to be deleted without going through a recycle bin.

Scroll to Top