BASH / CHAPTER 06

Patterns and filename-safe iteration

Intermediate

Distinguish shell patterns from data and handle empty matches deliberately.

By the end of this chapter

  • Use [[ ]] patterns intentionally
  • Account for unmatched filename globs
  • Preserve filenames containing spaces

The idea

Bash patterns such as *.txt are not regular expressions. Inside [[ $name == *.txt ]], the unquoted right side is a pattern, while quoting that right side makes it literal text. The left side remains a value under the special conditional syntax, avoiding ordinary word splitting. Decide whether a caller supplies a pattern or ordinary text before choosing the comparison form.

Filename expansion has a separate empty-match policy. By default, an unmatched glob can remain as a literal word; nullglob removes an unmatched pattern from the result. A robust file loop must choose that policy and quote each expanded filename when passing it onward. Spaces and wildcard characters inside actual filenames are data, so never reconstruct a command by joining names into one string for later evaluation.

Bash example
name="report one.txt"
if [[ $name == *.txt ]]; then printf 'text file\n'; fi
if [[ $name == "*.txt" ]]; then printf 'literal match\n'; fi
Result
text file

The first comparison interprets the suffix pattern; the second asks whether the whole name literally equals *.txt.

Try it yourself

Design a loop over text files that handles zero matches and filenames containing spaces.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

What changes when the pattern in [[ $name == "*.txt" ]] is quoted?