Skip to main content
RunBook Academy

LinuxII · Shell and Command-Line OperationsBulk operations

find, locate, and xargs — bulk operations on files

Intermediate⏱ ~10 min🧪 Lab requiredbashfindxargslocate

What you'll learn

  • Use find with name, type, size, mtime, and user predicates
  • Use xargs to feed file lists into commands safely
  • Avoid spaces-in-filenames bugs with null-delimited input
  • Compare locate vs find and when each is appropriate

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

The combination of find and xargs is how you apply a command to many files. The hazard is filenames with spaces, newlines, or quotes — a class of bug that has deleted production data when uncarefully composed.

find — predicate-based file selection

A find command is a series of predicates evaluated left to right. The most-used predicates:

PredicateEffect
-name '*.log'Match by glob (case-sensitive)
-iname '*.log'Case-insensitive name match
-type fRegular file
-type dDirectory
-type lSymbolic link
-size +100MLarger than 100 MiB
-mtime -7Modified in the last 7 days
-mtime +30Modified more than 30 days ago
-user aliceOwned by user alice
-group adminsOwned by group admins
-perm -u+wWritable by owner
-perm 0644Exactly mode 0644
-newer referenceModified after reference
! -name '*.gz'Negate a predicate

Predicates can be combined implicitly (AND) or with explicit -or and grouped with parens.

Read-only / Safefind old compressed logs
$ find /var/log -type f -name '*.gz' -mtime +30 | head
/var/log/nginx/access.log.10.gz
/var/log/nginx/access.log.11.gz
/var/log/nginx/error.log.5.gz
...

Illustrative output

Acting on matches

find can run a command on each match with -exec or pass them to xargs:

Destructivedelete old logs
$ find /var/log -type f -name '*.gz' -mtime +30 -delete

Illustrative output

Read-only / Safefind -exec
$ find /var/log -type f -name '*.gz' -mtime +30 -exec ls -lh {} +
-rw-r--r-- 1 root root 12M Aug  1 06:25 /var/log/nginx/access.log.10.gz
-rw-r--r-- 1 root root 14M Aug  1 06:25 /var/log/nginx/access.log.11.gz

Illustrative output

xargs — feeding file lists into commands

xargs reads whitespace-separated tokens from stdin and invokes a command with those tokens as arguments. The classic combination:

Read-only / Safefind piped to xargs
$ find /var/log -type f -name '*.gz' | xargs ls -lh
-rw-r--r-- 1 root root 12M Aug  1 06:25 /var/log/nginx/access.log.10.gz
...

Illustrative output

Read-only / Safenull-delimited find + xargs
$ find /var/log -type f -name '*.gz' -print0 | xargs -0 ls -lh
-rw-r--r-- 1 root root 12M Aug  1 06:25 /var/log/nginx/access.log.10.gz
...

Illustrative output

locate is faster than find for simple name searches because it queries a pre-built index (usually /var/lib/mlocate/mlocate.db or /var/lib/plocate/plocate.db). The index is rebuilt periodically by a daily cron job (the mlocate or plocate package).

Read-only / Safelocate
$ locate sshd_config | head
/etc/ssh/sshd_config
/usr/share/openssh/sshd_config.5.gz
/usr/share/man/man5/sshd_config.5.gz

Illustrative output

WhyThisMatters

Knowledge check

Knowledge check · 3 questions

  1. Q1. Which combination is the production-safe pattern for passing filenames with spaces through a pipeline?

  2. Q2. A file created five minutes ago will not show up in `locate` output until updatedb next runs.

  3. Q3. Which of the following are safe production patterns for deleting files? Select all that apply.

Passing score: 75%. Answers are checked in this browser.