惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 聂微东
IT之家
IT之家
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
博客园 - 【当耐特】
The Cloudflare Blog
宝玉的分享
宝玉的分享
罗磊的独立博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Visual Studio Blog
小众软件
小众软件
博客园_首页
Last Week in AI
Last Week in AI
J
Java Code Geeks
V
V2EX
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
阮一峰的网络日志
阮一峰的网络日志
腾讯CDC
博客园 - 司徒正美
Engineering at Meta
Engineering at Meta
The GitHub Blog
The GitHub Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
DataBreaches.Net
博客园 - 三生石上(FineUI控件)
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
Microsoft Azure Blog
Microsoft Azure Blog
T
The Blog of Author Tim Ferriss
N
Netflix TechBlog - Medium
F
Full Disclosure
B
Blog
H
Help Net Security
C
Check Point Blog
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Jina AI
Jina AI
酷 壳 – CoolShell
酷 壳 – CoolShell
Blog — PlanetScale
Blog — PlanetScale
L
LangChain Blog
P
Proofpoint News Feed
D
Docker
Microsoft Security Blog
Microsoft Security Blog

DigitalOcean Community Tutorials

Mastering grep with Regular Expressions for Efficient Text Search It's Time to Break Up with Your Cloud: Why AI Teams are Switching We Built a Private-Document AI App to Test Platform Security. Here Is What We Could Actually Verify. PostgreSQL Explained: A Complete Beginner-to-Advanced Guide How To Install and Configure Postfix on Ubuntu How To Build a Web Application Using Flask in Python 3 Build AI Reading List with DigitalOcean Functions and Mistral How To Concatenate Strings in Python How to Allow MySQL Remote Access Securely How To Install and Use Docker on Rocky Linux How To Build a Multi-Agent AI System with Docker Agent DSPy Use Cases: Build Optimized LLM Pipelines How To Submit AJAX Forms with jQuery Build an AI-Powered GPU Fleet Optimizer with the DigitalOcean AI Platform ADK Monitor GPU Utilization in Real Time: A Complete Guide Reduce File Size of Images in Linux - CLI and GUI methods Reduce PDF File Size in Linux: Tools and Methods How To Set Up a Private Docker Registry on Ubuntu How To Troubleshoot Terraform: Errors and Fixes How to Use Go Modules Python Multiprocessing Example: Process, Pool & Queue Convert Class Components to Functional Components with React Hooks How To Install and Configure Ansible on Ubuntu LLM Tokenizers Simplified: BPE, SentencePiece, and More How To Monitor System Authentication Logs on Ubuntu How to Use Traceroute and MTR to Diagnose Network Issues How to Deploy Postgres to Kubernetes Cluster Importing Packages in Go: A Complete Guide Create RAID Arrays with mdadm on Ubuntu How To Make an HTTP Server in Go How To Set Up Time Synchronization on Ubuntu How To Use Struct Tags in Go apt-key Deprecation: Add Repositories with GPG on Ubuntu Linux ps Command: 20 Real-World Examples Python struct.pack and struct.unpack for Binary Data Deadlock in Java: Examples, Detection, and Prevention Structured Resume Skill Extraction Using Mistral-7B Inference How to Use the Python Main Function How to Set Up NemoClaw on a DigitalOcean Droplet with 1-Click Build an End-to-End RAG Pipeline for LLM Applications From Single to Multi-Agent Systems: Key Infrastructure Needs Back Up Data to Object Storage Using Restic How to Generate Videos with LTX-2.3 on DigitalOcean GPU Droplets How To Install LAMP Stack (Apache, MySQL, PHP) on Ubuntu How to Download Files with cURL How To Use Variadic Functions in Go Generate UUIDs with uuidgen on Linux How To Use EJS to Template Your Node Application How to Install Node.js on Ubuntu (Step-by-Step Guide) MongoDB Indexes: Improve Query Performance with Node.js LLM Tool Calling with DigitalOcean AI Platform and Databases What are Text Diffusion Models? - An Overview Crafting a Game from Scratch with GPT-5.4 Building Long-Term Memory in AI Agents with LangGraph and Mem0 How To Install PHP 7.4 and Set Up a Local Development Environment on Ubuntu 20.04 Build a GraphQL API in Go to Upload Files to Spaces How To Lint and Format Code with ESLint in Visual Studio Code Train YOLO26 for Retail Object Detection on DigitalOcean GPUs How To Work with JSON in MySQL How to Use the JavaScript .map() Method Building a Scalable App with MongoDB Using DigitalOcean's MCP Server How to Create an SSH Key in Linux: Easy Step-by-Step Guide Measure MySQL Query Performance with mysqlslap How To Use *args and **kwargs in Python 3 Nemotron 3 helped me find the perfect dish rack? A2A vs MCP - How These AI Agent Protocols Actually Differ How To Install and Manage Supervisor Docker Container Images with Watchtower on Ubuntu Getting Started with Qwen3.5 Vision-Language Models How To Create a New Sudo-Enabled User on Ubuntu How to Use Ansible to Install and Set Up Docker on Ubuntu How To Enable Remote Desktop Protocol Using xrdp on Ubuntu 22.04 How To Convert a String to a List in Python How To Check If a String Contains Another String in Python How to Read a Properties File in Python Python Command Line Arguments: sys.argv, argparse, getopt Mastering Grep command in Linux/Unix: A Beginner's Tutorial Understanding Python Data Types How to Implement a Stack in C With Code Examples Python os.system() vs subprocess: Run System Commands How To Install and Use Docker Compose on Ubuntu How to Add and Delete Users on Ubuntu How To Order Query Results in Laravel Eloquent How To Define and Use Handlers in Ansible Playbooks How To Install and Use SQLite on Ubuntu How To Install and Use Homebrew on macOS How To Manage DateTime with Carbon in Laravel and PHP How To Install Git on Ubuntu How To Install and Secure Redis on Ubuntu How To Build and Install Go Programs on Linux Using ldflags to Set Version Information for Go Applications How To Build a Node.js Application with Docker How To Add JavaScript to HTML How To Reset Your MySQL or MariaDB Root Password How To Add Images in Markdown How To Set Up a Production Elasticsearch Cluster with Ansible How To Set Up a Firewall Using firewalld on CentOS Understanding Systemd Units and Unit Files How To Set Up Replication in MySQL How To Use the .htaccess File
How To Use Find and Locate to Search for Files on Linux
Justin Ellingwood · 2026-03-20 · via DigitalOcean Community Tutorials

Introduction

Linux gives you several tools for finding files, and each one solves a different problem. find walks the filesystem in real time, giving you precise control over what to match and what to do with the results. locate queries a pre-built index, making it the faster option when you need a quick path lookup and do not need results to reflect the last few seconds of filesystem activity. whereis and which are narrower tools focused on command binaries and man page locations, useful when you need to confirm which version of a program your shell will run.

Knowing which tool to reach for saves time. Running find / to locate a config file you just installed is slower than running locate against an up-to-date index. Conversely, using locate in a Docker container where updatedb has never run will return nothing at all. The right choice depends on whether you need real-time accuracy, how large the search scope is, and whether you intend to act on the results.

This tutorial covers each tool from basic usage through practical administration patterns: filtering by name, type, size, ownership, permissions, and modification time with find; managing the locate index with updatedb; running bulk actions with -exec and xargs; searching file contents with grep; and excluding directories from traversal with -prune.

Key Takeaways

  • Use find for real-time filesystem searches with filters such as name, ownership, permissions, size, timestamps, and depth.
  • Use locate for fast path lookups from an index, then run updatedb when recent files do not appear.
  • Use whereis and which to resolve binaries and command paths, not general file discovery.
  • Use -exec and xargs to act on results in bulk, and prefer batched execution for better performance.

Choosing Between find, locate, whereis, and which

Use find when accuracy and real-time results matter, and use locate when speed matters more than immediate freshness. whereis and which solve a narrower problem, command lookup, while fd is a modern alternative to find that is not installed by default on Debian and Ubuntu.

Tool Speed Real-Time Results Searches By Install Required
find Slower on large trees Yes Name, type, owner, permissions, size, time, depth, and more No
locate Very fast No, depends on index age Indexed path substrings, basename (-b) Usually (mlocate or plocate)
fd Fast Yes Name and pattern matching with simpler defaults Yes, apt install fd-find on Debian and Ubuntu
whereis Fast Yes Binary, source, and man page locations No
which Fast Yes First executable match in $PATH No

For day-to-day administration, start with find for precise filtering, use locate for quick broad lookup, and use whereis or which when validating command binaries. You can also review related Linux tooling in DigitalOcean’s Linux commands guide.

Prerequisites

To follow along with this guide, you need access to a Linux-based system, either a local machine or a remote server you log in to with SSH. The examples were validated on a Linux server running Ubuntu, and they also apply to Ubuntu and later versions as well as many other Linux distributions.

If you plan to use a remote server, complete the Initial Server Setup for Ubuntu first. This prepares a non-root user with sudo privileges and a firewall so you can run administrative commands safely.

Note: To illustrate how the find and locate commands work, the example commands in this guide search for files stored under /, or the root directory. Because of this, if you’re logged into the terminal as a non-root user, some of the example commands may include Permission denied in their output.

This is to be expected, since you’re searching for files within directories that regular users typically don’t have access to. However, these example commands should still work and be useful for understanding how these programs work.

Using the locate Command

Use locate when you need fast path lookups across the system and can accept results from an index that may be slightly out of date.

Install locate on Debian and Ubuntu by updating package metadata and installing plocate, which is the default on current Ubuntu releases:

  1. sudo apt update
  2. sudo apt install plocate

On older systems that use mlocate, install it with:

  1. sudo apt install mlocate

On Rocky Linux, CentOS, and other Red Hat-derived distributions, install with dnf:

  1. sudo dnf install mlocate

locate is faster than find because it reads from a database instead of walking the filesystem in real time. The basic form is:

  1. locate query

This returns paths containing query anywhere in the full path. To match only basenames, add -b:

  1. locate -b query

To return only existing paths and skip stale index entries, use -e:

  1. locate -e query

To inspect index statistics:

  1. locate -S
Database /var/lib/mlocate/mlocate.db:
    21015 directories
    136787 files
    7727763 bytes in file names
    3264413 bytes used to store database

How updatedb Works

updatedb builds the locate index by traversing mounted filesystems and recording paths in the database file. Most systems run it daily, often through /etc/cron.daily/mlocate, while newer systems may use a systemd timer managed by the plocate or mlocate package.

Run a manual database refresh when needed:

  1. sudo updatedb

updatedb behavior is controlled by /etc/updatedb.conf, including pruned paths and filesystems:

PRUNE_BIND_MOUNTS="yes"
PRUNEPATHS="/tmp /var/spool /media /var/lib/os-prober /var/lib/docker"
PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 devpts cgroup2"

Note: The values shown above are representative. Your system may include additional paths in PRUNEPATHS and additional filesystem types in PRUNEFS. Edit only the values relevant to your environment.

To exclude a directory from indexing, add it to PRUNEPATHS and run sudo updatedb again.

To verify the directory was excluded, run locate for a path inside it and confirm no results are returned:

  1. locate excluded_directory_path

If results still appear, confirm you saved /etc/updatedb.conf and that the updatedb command completed without errors.

Note: locate only reflects the last successful updatedb run. Files created, removed, or moved after that run will not appear correctly until the index updates again.

Warning: In Docker containers and other ephemeral filesystems, locate databases may be missing, stale, or reset when the container is recreated. Use find for guaranteed real-time checks in short-lived environments.

If you want to schedule your own refresh cadence, review this guide on scheduling routine tasks with cron and anacron.

Using the find Command

Use find when you need precise, real-time filtering across directories.

Finding by Name

Search by exact, case-sensitive filename with:

  1. find -name "query"

When no starting directory is specified, find searches from the current working directory.

For case-insensitive matching:

  1. find -iname "query"

To invert the search:

  1. find -not -name "query_to_avoid"

You can also invert with !, escaped so the shell does not interpret it first:

  1. find \! -name "query_to_avoid"

Finding by Type

Use -type when you need to restrict results to a specific kind of filesystem object, such as only regular files or only directories, regardless of their name.

Filter by file type with:

  1. find -type type_descriptor -name query

Common descriptors:

  • f: regular file
  • d: directory
  • l: symbolic link
  • c: character device
  • b: block device

Find character devices in /dev:

  1. find /dev -type c
/dev/vcsa5
/dev/vcsu5
/dev/vcs5
/dev/vcsa4
/dev/vcsu4
/dev/vcs4
/dev/vcsa3
/dev/vcsu3
/dev/vcs3
/dev/vcsa2
/dev/vcsu2
/dev/vcs2
. . .

Search for .conf files under /usr:

  1. find /usr -type f -name "*.conf"
/usr/src/linux-headers-5.4.0-88-generic/include/config/auto.conf
/usr/src/linux-headers-5.4.0-88-generic/include/config/tristate.conf
/usr/src/linux-headers-5.4.0-90-generic/include/config/auto.conf
/usr/src/linux-headers-5.4.0-90-generic/include/config/tristate.conf
/usr/share/adduser/adduser.conf
/usr/share/ufw/ufw.conf
/usr/share/popularity-contest/default.conf
/usr/share/byobu/keybindings/tmux-screen-keys.conf
/usr/share/libc-bin/nsswitch.conf
/usr/share/rsyslog/50-default.conf
. . .

Note: The previous example combines two find query expressions; namely, -type f and -name "*.conf". For any file to be returned, it must satisfy both of these expressions.

You can combine expressions like this by separating them with the -and option, but as this example shows the -and is implied any time you include two expressions. You can also return results that satisfy either expression by separating them with the -or option:

  1. find -name query_1 -or -name query_2

This example will find any files whose names match either query_1 or query_2.

Filtering by Time and Size

Use -size, -mtime, -atime, -ctime, and related flags to narrow results quickly.

Size

Filter by size with unit suffixes:

  • c: bytes
  • k: kilobytes
  • M: megabytes
  • G: gigabytes
  • b: 512-byte blocks

Find files exactly 50 bytes:

  1. find /usr -size 50c

Find files less than 50 bytes:

  1. find /usr -size -50c

Find files larger than 700 MB:

  1. find /usr -size +700M

Time

Use -mtime, -atime, and -ctime to filter files by when they were last modified, accessed, or had their metadata changed. Pass a positive integer for exactly N days ago, a negative integer (-N) for within the last N days, and a positive integer with + (+N) for more than N days ago.

  • Access time (-atime): the last time a file was read or written to.
  • Modification time (-mtime): the last time file contents changed.
  • Change time (-ctime): the last time inode metadata changed.

To find files modified within the last day, use -1 to mean less than one day ago:

  1. find /usr -mtime -1

Using 1 without a sign matches files modified exactly one day ago, which is rarely what you want. Using -1 matches anything within the last 24 hours.

To find files accessed within the last day, run:

  1. find /usr -atime -1

To find files whose metadata changed more than three days ago, run:

  1. find /usr -ctime +3

These options also have companion parameters you can use to specify minutes instead of days:

  1. find /usr -mmin -1

This will give the files that have been modified in the last minute.

Use -newer to compare against a reference file:

  1. find / -newer reference_file

This syntax will return every file on the system that was created or changed more recently than the reference file.

Finding by Owner and Permissions

Search files by owner with -user and by group with -group:

  1. find /var -user syslog

Similarly, you can specify files in the /etc directory owned by the shadow group by typing:

  1. find /etc -group shadow

You can also search by permissions, which is useful when auditing access controls. For a deeper permissions refresher, read An Introduction to Linux Permissions.

Note: Searching from / traverses the entire filesystem and may produce significant Permission denied output for non-root users. Scope your search to a specific directory such as /home or /var when possible.

Match an exact mode:

  1. find / -perm 644

This will match files with exactly the permissions specified.

Match files with at least these permissions:

  1. find / -perm -644

This will match any files that have additional permissions. A file with permissions of 744 would be matched in this instance.

Finding Empty Files and Directories

Use -empty to find files or directories that contain no data or no entries. This is useful for cleaning up placeholder files and empty directories left by installers or build tools.

Find empty files:

  1. find /tmp -type f -empty

Find empty directories:

  1. find /tmp -type d -empty

Executing Actions on Search Results with -exec and xargs

Use -exec for direct per-result actions inside find, and use xargs when you want batched or parallel command execution.

Run one command per matched file:

  1. find find_parameters -exec command_and_options {} \;

The {} token is replaced by each matched path. The \; terminates the command.

For example, from /tmp/test, update matching file modes:

  1. find . -type f -perm 644 -exec chmod 664 {} \;

Change matching directory modes:

  1. find . -type d -perm 755 -exec chmod 700 {} \;

Bulk Deletion and Batched Execution

Delete temporary .bak files:

  1. find /tmp/test -type f -name "*.bak" -exec rm {} \;

If no matching files exist, the command runs silently and returns to the prompt.

When you use -exec ... {} \;, find starts one subprocess per match, which adds overhead on large result sets. Batched mode with -exec ... {} + passes many paths at once, which reduces process creation and usually runs faster:

  1. find /tmp/test -type f -name "*.log" -exec rm {} +

The same silent behavior applies when batching with {} + and no matches are found.

Warning: Deletion commands are destructive. Test first with the same find query without -exec rm, or replace rm with ls -l for a dry run.

Using xargs for Chaining and Parallelism

xargs reads path lists from standard input and builds command lines efficiently. This is useful when you want parallel execution, explicit batching, or commands not directly attached to find.

Count matching files, then gzip them in parallel with 4 workers:

  1. find /var/log -type f -name "*.log" | wc -l
42
  1. find /var/log -type f -name "*.log" -print0 | xargs -0 -n 10 -P 4 gzip

If the files compress successfully, the command runs silently and returns to the prompt.

In practice, use -exec ... {} + when you want simple, safe batching directly in find. Use xargs when you need options like parallel workers (-P), fixed batch sizes (-n), or more complex command chaining.

Searching File Content with find and grep

Use find to select files by name or type, then pipe or pass those results to grep to search inside them.

Search all .conf files under /etc for a specific string, with the filename printed alongside each match:

  1. find /etc -type f -name "*.conf" -exec grep -H "PermitRootLogin" {} \;
/etc/ssh/sshd_config:PermitRootLogin no

The -H flag tells grep to include the filename in the output. Without it, you see only the matching line, which makes it impossible to tell which file it came from when multiple files match.

To return only the filenames that contain a match, without printing the matching lines themselves, use -l:

  1. find /etc -type f -name "*.conf" -exec grep -l "PermitRootLogin" {} \;
/etc/ssh/sshd_config

For file names that contain spaces or special characters, use -print0 with xargs -0 to handle them safely:

  1. find /etc -type f -name "*.conf" -print0 | xargs -0 grep -H "127.0.0.1"

On large directory trees, the xargs form is faster than -exec grep {} \; because it passes multiple files to a single grep invocation instead of spawning one process per file.

Using whereis and which for Binary and Path Lookup

Use whereis and which to locate command-related paths, not arbitrary files.

whereis returns binary, source, and man page locations when present:

  1. whereis ls
ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz

You can query multiple commands at once:

  1. whereis find grep ssh
find: /usr/bin/find /usr/share/man/man1/find.1.gz
grep: /usr/bin/grep /usr/share/man/man1/grep.1.gz
ssh: /usr/bin/ssh /usr/share/man/man1/ssh.1.gz

which returns the first executable match in the current $PATH:

  1. which python3
/usr/bin/python3

Use which when you need to verify which binary a shell session will invoke, particularly when multiple versions of the same tool are installed. Use whereis when you also need man page locations. For general filesystem discovery, use find, because whereis and which do not apply ownership, permission, size, time, or depth filters.

To narrow whereis output to a specific location type, use the -b, -m, or -s flags:

  1. whereis -b find
find: /usr/bin/find

-b returns the binary path only. -m returns the man page path only. -s returns the source path only, if present.

Use which to confirm a command is available and locate its binary:

  1. which htop
/usr/bin/htop

If the command is installed but which returns nothing, check whether its directory is included in $PATH:

  1. echo $PATH

On systems with multiple Python versions, which python3 and which python may return different paths. Use which to confirm which binary your shell will invoke before running scripts that depend on a specific version.

Advanced find Techniques

Use advanced predicates when you need tighter control over traversal depth or want to exclude specific directories from a search.

Filtering by Depth

Use -maxdepth and -mindepth to control how many directory levels find descends. This is useful when you know files exist at a specific depth and want to avoid traversing an entire tree.

To follow the examples below, create a test directory structure in /tmp/. Files and directories under /tmp/ are removed on the next reboot, so this will not clutter your system.

After running the commands in this section, your /tmp/ directory will contain three levels of directories, with 10 directories at the first level. Each directory, including the temporary directory, will contain 10 files and 10 subdirectories.

Create the example directory structure within the /tmp/ directory with the following command:

  1. mkdir -p /tmp/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}

Following that, populate these directories with some sample files using the touch command:

  1. touch /tmp/test/{file{1..10},level1dir{1..10}/{file{1..10},level2dir{1..10}/{file{1..10},level3dir{1..10}/file{1..10}}}}

With these files and directories in place, navigate into the test/ directory you just created:

  1. cd /tmp/test

To get a baseline understanding of how find will retrieve files from this structure, begin with a regular name search that matches any files named file1:

  1. find -name "file1"
./level1dir7/level2dir8/level3dir9/file1
./level1dir7/level2dir8/level3dir3/file1
./level1dir7/level2dir8/level3dir4/file1
./level1dir7/level2dir8/level3dir1/file1
./level1dir7/level2dir8/level3dir8/file1
./level1dir7/level2dir8/level3dir7/file1
./level1dir7/level2dir8/level3dir2/file1
./level1dir7/level2dir8/level3dir6/file1
./level1dir7/level2dir8/level3dir5/file1
./level1dir7/level2dir8/file1
. . .

Note: Always quote name arguments passed to -name and -iname. Without quotes, the shell may expand glob characters such as * or ? before find sees them, producing unexpected results.

This will return a lot of results. If you pipe the output into a counter, you’ll find that there are 1111 total results:

  1. find -name "file1" | wc -l
1111

This is probably too many results to be useful to you in most circumstances. To narrow it down, you can specify the maximum depth of the search under the top-level search directory:

  1. find -maxdepth num -name query

To find file1 only in the level1 directories and above, you can specify a max depth of 2 (1 for the top-level directory, and 1 for the level1 directories):

  1. find -maxdepth 2 -name "file1"
./level1dir7/file1
./level1dir1/file1
./level1dir3/file1
./level1dir8/file1
./level1dir6/file1
./file1
./level1dir2/file1
./level1dir9/file1
./level1dir4/file1
./level1dir5/file1
./level1dir10/file1

That is a much more manageable list.

You can also set a minimum depth if you know the files you need are nested beyond a certain level:

  1. find -mindepth num -name query

You can use this to find only the files at the end of the directory branches:

  1. find -mindepth 4 -name "file1"
./level1dir7/level2dir8/level3dir9/file1
./level1dir7/level2dir8/level3dir3/file1
./level1dir7/level2dir8/level3dir4/file1
./level1dir7/level2dir8/level3dir1/file1
./level1dir7/level2dir8/level3dir8/file1
./level1dir7/level2dir8/level3dir7/file1
./level1dir7/level2dir8/level3dir2/file1
. . .

Again, because of the branching directory structure, this will return a large number of results (1000).

You can combine the min and max depth parameters to focus in on a narrow range:

  1. find -mindepth 2 -maxdepth 3 -name "file1"
./level1dir7/level2dir8/file1
./level1dir7/level2dir5/file1
./level1dir7/level2dir7/file1
./level1dir7/level2dir2/file1
./level1dir7/level2dir10/file1
./level1dir7/level2dir6/file1
./level1dir7/level2dir3/file1
./level1dir7/level2dir4/file1
./level1dir7/file1
. . .

Combining these options like this narrows down the results significantly, with only 110 lines returned instead of the previous 1000.

Excluding Directories with -prune

Use -prune to skip specific directories during a search. This prevents find from descending into directories like .git, node_modules, or vendor paths that would otherwise produce noise or slow the search significantly.

Search for .js files while skipping the node_modules directory:

  1. find . -type d -name "node_modules" -prune -o -type f -name "*.js" -print

The -o operator means OR. find prunes the node_modules directory and then, for everything else, prints .js files. Without -print at the end, find would also print the pruned directory name itself.

Note: -prune does not delete directories. It only tells find not to descend into them during the current search.

Frequently Asked Questions

Q: What is the difference between the find and locate commands in Linux?

A: find walks the filesystem in real time, so its results reflect the current state immediately. locate queries an indexed database, which is much faster on large systems. locate can miss very recent changes until updatedb runs.

Q: How do I update the locate database manually?

A: Run sudo updatedb to rebuild the locate index on demand. This command refreshes the file path database used by locate. If permissions block some paths, run it with appropriate privileges.

Q: How do I search for a file by name using the find command?

A: Use find -name "query" for case-sensitive matching by filename pattern. Use find -iname "query" to ignore case. Add a start directory such as find /etc -name "*.conf" to scope the search.

Q: How do I search inside file contents in Linux?

A: Combine find with grep, for example find /etc -type f -name "*.conf" -exec grep -H "pattern" {} \;. This filters by filename first, then searches content. For safer handling of special characters in filenames, use -print0 with xargs -0.

Q: What does the -exec flag do in the find command?

A: -exec runs another command on each match returned by find. The {} placeholder is replaced by the matched path. Use \; for one command per file, or + for batched execution.

Q: When should I use xargs instead of -exec?

A: Use xargs when you need explicit batching with -n, parallelism with -P, or command pipelines fed from standard input. It is often faster on large result sets because it groups many files per invocation. Use -print0 and xargs -0 to handle spaces and special characters safely.

Q: What is the difference between whereis and which?

A: which returns the first executable found in your $PATH, which helps confirm what runs in your shell. whereis can return binary, source, and man page locations. Neither command replaces find for general file search.

Q: Does locate work inside Docker containers or ephemeral filesystems?

A: It depends on whether an index exists and is kept current in that runtime. Many short-lived containers do not maintain a useful locate database between restarts. In those environments, prefer find for accurate results.

Conclusion

Use find when you need immediate, filter-rich results, and use locate when you need fast indexed lookups. Add whereis and which when validating executable paths and man page locations in shell and package troubleshooting workflows.

For continued practice, read man find, man locate, and info find. You can also expand your command line toolkit with DigitalOcean’s Linux commands tutorial.

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.