Find with shell with different and/or conditions

Learn find with shell with different and/or conditions with practical examples, diagrams, and best practices. Covers linux, shell, find development techniques with visual explanations.

Mastering the find Command with AND/OR Conditions in Shell

A stylized magnifying glass icon over a file system directory structure, illustrating the concept of searching for files with complex logic.

Learn how to use the powerful find command in Linux and Unix-like systems to locate files and directories based on complex criteria involving logical AND and OR conditions.

The find command is an indispensable tool for navigating and managing file systems in Linux and Unix-like environments. While its basic usage is straightforward, its true power lies in combining multiple search criteria using logical operators. This article will guide you through constructing find commands with AND and OR conditions, enabling you to perform highly specific and efficient file searches.

Understanding find's Logical Operators

The find command processes expressions from left to right. By default, multiple expressions are implicitly combined with an AND operator. To explicitly define AND or OR relationships, find provides specific operators:

  • -a or no operator (implicit): Logical AND. Both conditions must be true.
  • -o: Logical OR. At least one condition must be true.
  • ! or -not: Logical NOT. Negates the following condition.
  • \( \): Grouping. Used to control the order of evaluation, similar to parentheses in mathematical expressions. These need to be escaped to prevent the shell from interpreting them.

Combining Conditions with AND

By default, when you specify multiple conditions without an explicit operator, find treats them as an AND operation. This means a file must satisfy all specified conditions to be included in the results. You can also explicitly use the -a operator, though it's often omitted for brevity.

find . -type f -name "*.log" -size +1M
# Equivalent to:
find . -type f -a -name "*.log" -a -size +1M

Finding log files larger than 1MB

In the example above, find will search the current directory (.) for files (-type f) that end with .log (-name "*.log") AND are larger than 1 megabyte (-size +1M). All three conditions must be met.

Combining Conditions with OR

The -o operator allows you to find files that match at least one of several conditions. This is particularly useful when you're looking for files that could have different names, types, or other attributes.

find . -name "*.txt" -o -name "*.md"

Finding files ending with .txt OR .md

This command will locate all files in the current directory and its subdirectories that either end with .txt OR end with .md.

Advanced Logic with Grouping and NOT

When combining AND and OR conditions, the order of operations matters. find evaluates AND before OR by default. To override this precedence and create more complex logic, you use escaped parentheses \( \) for grouping. The ! or -not operator negates the condition that follows it.

find . -type f \( -name "*.log" -o -name "*.tmp" \) -size +10M

Finding log or temporary files larger than 10MB

Here, the parentheses ensure that find first evaluates (-name "*.log" -o -name "*.tmp"). This means it looks for files that are either .log OR .tmp. The result of this OR operation is then ANDed with the -size +10M condition. So, it finds files that are either .log or .tmp AND are larger than 10MB.

find . -type f -not -name "*.bak" -mtime -7

Finding files not ending with .bak, modified in the last 7 days

This command finds all regular files (-type f) that do NOT end with .bak (-not -name "*.bak") AND were modified within the last 7 days (-mtime -7).

A flowchart diagram illustrating the logical evaluation of a complex find command. It shows a starting point, then a decision node for 'Is it a file?', followed by a grouped decision 'Is name *.log OR *.tmp?', and finally a decision 'Is size > 10MB?'. Arrows connect the decisions to a final 'Result' box if all conditions are met. Blue boxes for actions, green diamonds for decisions, arrows showing flow direction. Clean, technical style.

Logical flow for find . -type f \( -name "*.log" -o -name "*.tmp" \) -size +10M

Practical Examples

Let's look at a few more practical scenarios to solidify your understanding.

find /var/log -type f \( -name "*.gz" -o -name "*.zip" \) -mtime +30 -delete

Delete compressed log files older than 30 days

This command searches /var/log for regular files that are either .gz or .zip AND were last modified more than 30 days ago, then deletes them. Use -delete with caution!

find . -maxdepth 1 -type d \( -name "temp*" -o -name "cache*" \) -exec rm -rf {} +

Remove 'temp' or 'cache' directories in the current directory only

Here, find looks only in the current directory (-maxdepth 1) for directories (-type d) named temp* OR cache*, and then removes them recursively. The -exec ... + option is more efficient than -exec ... \; for multiple files.