# How I build a find command without deleting the wrong files

A beginner-friendly guide to using find safely: name filters, file types, size and age checks, preview first, then delete only when the result is correct.

- Date: 2026-09-27
- URL: https://ilham.dev/posts/how-to-build-find-command-safely/
- Markdown: https://ilham.dev/posts/how-to-build-find-command-safely/index.md
- Tags: linux, find, devops, tools
- Reading time: 4 min


The `find` command is one of the most useful Linux commands, but it is also one of
the commands I treat with respect. It can search thousands of files very quickly,
and with the wrong option it can also delete thousands of files very quickly.

That is why I like building the command slowly with the
[find Command Builder](/tools/find-command-builder/). The goal is not only to make a
valid command. The goal is to make a command I understand before I run it.

## The simple idea

`find` walks through a directory tree and checks every file or folder against rules
you give it.

A very simple command looks like this:

```sh
find /var/log -name "*.log"
```

Plain meaning:

> Start in `/var/log` and show anything whose name ends with `.log`.

The important parts are:

```text
find <where to start> <rules> <what to do>
```

If you do not tell `find` what to do, it usually prints the matches.

## Step 1: choose the starting directory

Start with the smallest directory that makes sense.

Bad idea:

```sh
find / -name "*.log"
```

Better idea:

```sh
find /var/log -name "*.log"
```

Searching from `/` means searching almost the whole system. That is slower and can
produce noisy permission errors. If I know the files are under `/var/log`, I start
there.

In the [find Command Builder](/tools/find-command-builder/), the starting directory
is the first thing I decide.

## Step 2: filter by file type

If I only want files, I add:

```sh
-type f
```

If I only want directories:

```sh
-type d
```

Example:

```sh
find /var/log -type f -name "*.log"
```

Plain meaning:

> Search under `/var/log`, but only return files, not directories.

This keeps the result cleaner.

## Step 3: filter by name

Name filters are common:

```sh
-name "*.log"
-name "*.tmp"
-name "backup-*"
```

Use quotes around patterns. Without quotes, the shell may expand the pattern before
`find` sees it.

Good:

```sh
find . -name "*.log"
```

Risky:

```sh
find . -name *.log
```

If the current directory already contains `.log` files, the shell may replace
`*.log` with those filenames. Quoting avoids that surprise.

## Step 4: filter by age

Age filters help when cleaning old files.

Example:

```sh
find /var/log -type f -name "*.log" -mtime +30
```

Plain meaning:

> Find `.log` files modified more than 30 days ago.

The `+30` part means older than 30 days. A minus sign means newer than:

```sh
-mtime -7
```

means modified within the last 7 days.

I always read age filters twice before using them with delete.

## Step 5: filter by size

Size filters are useful for finding large files:

```sh
find /var/log -type f -size +100M
```

Plain meaning:

> Find files larger than 100 MB.

Common suffixes:

- `k` for kilobytes;
- `M` for megabytes;
- `G` for gigabytes.

Example:

```sh
find /home/ubuntu -type f -size +1G
```

This helps find files that may be filling a disk.

## Step 6: preview first

Before deleting or running another command, print the matches first.

Example:

```sh
find /tmp -type f -name "*.tmp" -mtime +7 -print
```

Look at the output. Ask:

- are these really the files I want?
- is the directory correct?
- is the age filter correct?
- are there unexpected matches?

This preview step is the safety belt.

## Step 7: delete only after the preview is correct

After the preview is correct, then use delete:

```sh
find /tmp -type f -name "*.tmp" -mtime +7 -delete
```

I prefer `-delete` only when the command is simple and already previewed.

Do not build a delete command as the first version. Build the print version first,
then change the action.

## Step 8: use max depth when needed

Sometimes I only want to search one level deep.

```sh
find /var/www -maxdepth 1 -type d
```

Plain meaning:

> Look only directly inside `/var/www`, not deep inside every project.

This is useful when the top-level folders matter but the contents would be too much.

## Step 9: be careful with exec

`find` can run a command for each match:

```sh
find . -type f -name "*.log" -exec gzip {} \;
```

Here, `{}` means “the matched file”.

This is powerful, but I use it carefully. First I preview the files. Then I run the
`-exec` version only if the list is right.

For commands that can handle many files at once, this form is often better:

```sh
find . -type f -name "*.log" -exec gzip {} +
```

The `+` version groups files together instead of running the command once per file.

## My safe workflow

When I need a `find` command, I follow this order:

1. choose the smallest starting directory;
2. add `-type f` or `-type d`;
3. add name, age, or size filters;
4. print the results;
5. review the output;
6. only then add `-delete` or `-exec`.

The [find Command Builder](/tools/find-command-builder/) is useful because it makes
that slow, safe process easier. It helps me build the command one decision at a
time instead of typing a dangerous one-liner from memory.

The simple rule is:

> Print first. Delete later.
