Wildcards, Tree, and Navigation Tools

Summary: in this tutorial, you will learn master wildcards and globbing patterns, the tree command for visual directory display, and additional navigation utilities.

Wildcards, Tree, and Navigation Tools

Now that you know the basic navigation commands, it's time to learn the tools that make you truly fast in the terminal. Wildcards let you match multiple files with a single pattern, tree gives you a visual overview of directory structures, and commands like pushd/popd let you jump between directories effortlessly.

Wildcards (Globbing)

Wildcards (also called "globbing") let you match multiple files at once using patterns. The shell expands these patterns before passing them to commands.

Basic Wildcards

WildcardMeaningExampleMatches
*Any number of any characters*.txtfile.txt, document.txt, report_2024.txt
?Exactly one characterfile?.txtfile1.txt, fileA.txt (not file10.txt)
[abc]One character from the setfile[123].txtfile1.txt, file2.txt, file3.txt
[a-z]One character from the rangefile[a-z].txtfilea.txt through filez.txt
[!abc]One character NOT in the setfile[!0-9].txtfileA.txt (not file1.txt)

Advanced Wildcards (Bash Extended Globbing)

Enable with shopt -s extglob:

PatternMeaningExample
?(pattern)Zero or one occurrencefile?(s).txt matches file.txt, files.txt
*(pattern)Zero or more occurrencesfile*([0-9]).txt matches file.txt, file1.txt, file123.txt
+(pattern)One or more occurrencesfile+([0-9]).txt matches file1.txt, file123.txt (not file.txt)
@(pattern)Exactly one occurrence@(file|doc).txt matches file.txt or doc.txt
!(pattern)Anything except pattern!(*.log) matches everything except .log files

Brace Expansion

# Create multiple files at once
touch file{1,2,3}.txt
# Creates: file1.txt, file2.txt, file3.txt
 
# Numeric ranges
touch file{1..10}.txt
# Creates: file1.txt through file10.txt
 
# Alphabetic ranges
mkdir dir{a..z}
# Creates: dira, dirb, ..., dirz
 
# Combine patterns
touch {report,memo,letter}_{2024..2026}.{txt,pdf}
# Creates: report_2024.txt, report_2024.pdf, report_2025.txt, etc.
 

Wildcard Examples

# All text files in current directory
ls *.txt
 
# All files starting with "report"
ls report*
 
# Files like data1.csv, data2.csv, ... data9.csv
ls data?.csv
 
# All CSV files
ls *.csv
 
# Files with a vowel as second character
ls ?[aeiou]*
 
# JPEG and PNG images
ls *.{jpg,png,gif}
ls *.jpg *.png *.gif      # Same thing
 
# All files except .log files (requires extglob)
shopt -s extglob
ls !(*.log)
 
# All Python files in all subdirectories (requires globstar)
shopt -s globstar
ls **/*.py
 
# Files modified today
ls -l *.txt | grep "$(date '+%b %e')"
 
# Backup all .conf files
cp /etc/*.conf ~/backup/
 
# Remove all temporary files
rm /tmp/temp_*
 

⚠️ Wildcards expand before command execution

The shell expands wildcards BEFORE running the command. This means:

ls *.txt
# Shell expands to: ls file1.txt file2.txt file3.txt
# Then runs ls with those arguments
 
# If no matches, you get an error:
ls *.xyz
# bash: No such file or directory
 

This is different from some other systems where the command does the expansion.

tree — Visual Directory Structure

The tree command shows a visual, hierarchical representation of directory structure. It's not always installed by default but is incredibly useful.

Installing tree

# Ubuntu/Debian
sudo apt install tree
 
# macOS
brew install tree
 
# Fedora/RHEL/CentOS
sudo dnf install tree
 

Using tree

# Basic usage (show everything in current directory)
tree
 
# Limit depth to 2 levels
tree -L 2
 
# Show only directories (no files)
tree -d
 
# Show hidden files
tree -a
 
# Show file sizes
tree -h
 
# Show file sizes with units
tree -sh
 
# Show only specific file types
tree -P "*.py"           # Only Python files
tree -P "*.{js,ts}"      # JavaScript and TypeScript files
 
# Exclude patterns
tree -I "node_modules|__pycache__|*.pyc"
 
# Show full path for each file
tree -f
 
# Sort by modification time
tree -t
 
# Show permissions
tree -p
 
# Combine options
tree -L 3 -h -a --dirsfirst
 

Example tree Output

tree -L 2 ~/Projects/my-app
 

Output:


/home/alice/Projects/my-app
├── README.md
├── package.json
├── src/
│   ├── index.js
│   ├── components/
│   └── utils/
├── tests/
│   ├── unit/
│   └── integration/
├── docs/
│   └── api.md
└── node_modules/
    ├── express/
    └── lodash/

7 directories, 4 files

Why tree is useful:

  • Project overview: Quickly understand project structure
  • Documentation: Include in README files to show layout
  • Debugging: Find where files are located
  • Teaching: Show filesystem concepts visually

Additional Navigation Commands

file — Identify File Types

Linux doesn't rely on file extensions to determine file type. The file command examines the actual contents:

file document.txt
# document.txt: UTF-8 Unicode text
 
file photo.jpg
# photo.jpg: JPEG image data, JFIF standard 1.01
 
file script.sh
# script.sh: Bash script, ASCII text executable
 
file /bin/ls
# /bin/ls: ELF 64-bit LSB pie executable, x86-64
 
file archive.tar.gz
# archive.tar.gz: gzip compressed data
 
file mystery_file
# Tells you what it actually is, regardless of name or extension
 
# Check multiple files
file *
 
# Be brief (just show type)
file -b document.txt
# UTF-8 Unicode text
 
# Show MIME type (useful for web servers)
file -i document.txt
# document.txt: text/plain; charset=utf-8
 

Why this matters: Files can be misnamed or have no extension. file examines the actual content to determine type.

stat — Detailed File Information

The stat command shows comprehensive file metadata:

stat document.txt
 

Output:


  File: document.txt
  Size: 4096       Blocks: 8          IO Block: 4096   regular file
Device: 802h/2050d  Inode: 1234567    Links: 1
Access: (0644/-rw-r--r--)  Uid: (1000/alice)   Gid: (1000/staff)
Access: 2024-01-15 10:30:00.000000000 +0000
Modify: 2024-01-15 10:30:00.000000000 +0000
Change: 2024-01-15 10:30:00.000000000 +0000
 Birth: 2024-01-14 08:00:00.000000000 +0000

Key information:

  • Size: File size in bytes
  • Blocks: Disk blocks used (filesystem-dependent)
  • Inode: Unique identifier for this file on the filesystem
  • Links: Number of hard links pointing to this file
  • Access time: Last time file was read
  • Modify time: Last time file content was changed
  • Change time: Last time file metadata (permissions, ownership) was changed
  • Birth time: When file was created (if filesystem supports it)
# Just show modification time (useful in scripts)
stat -c %Y document.txt
# 1705317000
 
# Human-readable format
stat -c "%n: %s bytes, modified %y" document.txt
# document.txt: 4096 bytes, modified 2024-01-15 10:30:00.000000000 +0000
 

basename and dirname

Extract parts of paths:

# Get just the filename (remove directory path)
basename /home/alice/Documents/report.txt
# report.txt
 
# Get just the filename without extension
basename /home/alice/Documents/report.txt .txt
# report
 
# Get just the directory path (remove filename)
dirname /home/alice/Documents/report.txt
# /home/alice/Documents
 

Useful in scripts:

# Process all files in a directory
for file in /var/log/*.log; do
    filename=$(basename "$file")
    dir=$(dirname "$file")
    echo "Processing $filename in $dir"
done
 

Exercises

🏋️ Exercise 1: Navigation Practice

Complete these navigation tasks in your terminal:

Task 1: Starting from your home directory, navigate to /tmp, then to /etc, then back to your home directory using only cd - and cd ~.

💡 Hint
Use cd /tmp, then cd /etc, then cd ~ to go home. Try cd - to toggle between the last two directories.
Show Solution
cd ~          # Start at home
pwd           # /home/username
cd /tmp       # Go to /tmp
pwd           # /tmp
cd /etc       # Go to /etc
pwd           # /etc
cd -          # Back to /tmp (toggles to previous directory)
pwd           # /tmp
cd -          # Back to /etc
pwd           # /etc
cd ~          # Go home
pwd           # /home/username
 
# Bonus: cd without arguments also goes home
cd
pwd           # /home/username
 

Task 2: List all files (including hidden) in your home directory in long format with human-readable sizes, sorted by modification time (newest first).

Show Solution
ls -laht ~
# -l: long format (permissions, owner, size, date)
# -a: all files (including hidden files starting with .)
# -h: human-readable sizes (KB, MB, GB instead of bytes)
# -t: sort by modification time (newest first)
 
# Sample output:
# drwxr-xr-x  25 alice  staff  800B Jan 15 10:35 .
# -rw-r--r--   1 alice  staff  1.2K Jan 15 10:30 .bashrc
# -rw-r--r--   1 alice  staff  4.0K Jan 14 09:15 document.txt
# drwxr-xr-x   5 alice  staff  160B Jan 13 08:00 Documents
 

Task 3: Using wildcards, list all .conf files in /etc (you may need sudo for some directories).

Show Solution
# List .conf files directly in /etc
ls /etc/*.conf
 
# Common output:
# /etc/host.conf  /etc/nsswitch.conf  /etc/resolv.conf
 
# For recursive search including subdirectories:
ls /etc/**/*.conf 2>/dev/null     # Requires: shopt -s globstar
# The 2>/dev/null suppresses permission errors
 
# Or better yet, use find:
find /etc -name "*.conf" 2>/dev/null | head -20
# This searches all subdirectories and handles permissions gracefully
 

Task 4: Show the directory tree of /etc but only 2 levels deep, directories only.

Show Solution
tree -L 2 -d /etc
# -L 2: limit to 2 levels deep
# -d: directories only (no files)
 
# Sample output:
# /etc
# ├── alternatives
# ├── apache2
# │   ├── conf-available
# │   ├── conf-enabled
# │   ├── mods-available
# │   └── mods-enabled
# ├── apt
# │   ├── apt.conf.d
# │   ├── preferences.d
# │   └── sources.list.d
# └── systemd
#     ├── system
#     └── user
 
# If tree is not installed:
# Ubuntu/Debian: sudo apt install tree
# macOS: brew install tree
 
🏋️ Exercise 2: Path Challenge

Given this directory structure:


/home/alice/
├── Documents/
│   ├── work/
│   │   ├── report.txt
│   │   └── data.csv
│   └── personal/
│       └── diary.txt
├── Downloads/
│   └── photo.jpg
└── .bashrc

Q1: If you are in /home/alice/Documents/work/, what is the relative path to diary.txt?

Show Solution

../personal/diary.txt

Explanation:

  • .. goes up one level to /home/alice/Documents/
  • Then personal/diary.txt goes down into personal/ and finds diary.txt
  • The path is relative to your current location (/home/alice/Documents/work/)

Q2: If you are in /home/alice/Downloads/, what is the relative path to report.txt?

Show Solution

../Documents/work/report.txt

Explanation:

  • .. goes up one level to /home/alice/
  • Then Documents/work/report.txt goes down through Documents/, into work/, and finds report.txt

Q3: What command would show all hidden files in alice's home directory?

Show Solution
ls -la /home/alice
# or if you're alice:
ls -la ~
# or just:
ls -la
 
# The -a flag shows "all" files, including hidden ones
# Hidden files start with a dot (.), like .bashrc, .bash_history, .ssh/
 
# To show ONLY hidden files:
ls -ld ~/.[^.]*
# This pattern matches files starting with . but not .. (parent directory)
 

Q4: Write a command that lists only directories in the current location.

Show Solution
# Method 1: Using ls with wildcard
ls -ld */
 
# Method 2: Using ls with grep
ls -l | grep '^d'
 
# Method 3: Using find
find . -maxdepth 1 -type d
 
# Method 4: Using tree
tree -L 1 -d
 
# The simplest and most reliable: ls -ld */
# The */ wildcard matches only directories
 
🏋️ Exercise 3: Wildcard Mastery

Practice these wildcard patterns (create test files first):

# Setup: Create test files
cd /tmp
mkdir wildcard-practice
cd wildcard-practice
touch file1.txt file2.txt file10.txt fileA.txt
touch report_2023.pdf report_2024.pdf report_2025.doc
touch image1.jpg image2.png photo.gif
 

Task 1: List only files that end with .txt and have a single digit in the name.

Show Solution
ls file?.txt
# Matches: file1.txt, file2.txt, fileA.txt
# Does NOT match: file10.txt (two digits)
 
# To match only numeric digits:
ls file[0-9].txt
# Matches: file1.txt, file2.txt
# Does NOT match: fileA.txt
 

Task 2: List all PDF files from 2024 or later.

Show Solution
ls report_202[4-5].pdf
# Matches: report_2024.pdf, report_2025.pdf
# Does NOT match: report_2023.pdf
 
# Or for any year starting with 202:
ls report_202*.pdf
# Matches: report_2023.pdf, report_2024.pdf, report_2025.pdf
 

Task 3: List all image files (jpg, png, gif).

Show Solution
# Method 1: Brace expansion
ls *.{jpg,png,gif}
# Matches: image1.jpg, image2.png, photo.gif
 
# Method 2: Multiple wildcards
ls *.jpg *.png *.gif
 
# Method 3: Extended globbing (requires shopt -s extglob)
shopt -s extglob
ls *.@(jpg|png|gif)
 

Task 4: Delete all files EXCEPT .txt files.

Show Solution
# DANGER: Test with ls first before using rm!
 
# Enable extended globbing
shopt -s extglob
 
# List files to be deleted (SAFE - test first!)
ls !(*.txt)
# Shows: report_2023.pdf, report_2024.pdf, report_2025.doc,
#        image1.jpg, image2.png, photo.gif
 
# If that looks correct, delete them:
rm !(*.txt)
 
# Verify:
ls
# Should show only: file1.txt, file2.txt, file10.txt, fileA.txt
 

Always test wildcard patterns with ls before using them with destructive commands like rm!


Summary

Mastering filesystem navigation is the foundation of Linux command-line proficiency:

  • Directory structure: Linux follows FHS; understanding /, /etc, /home, /var helps you know where things are
  • Paths: Absolute paths start with /, relative paths don't; use ~ for home, .. for parent, . for current
  • pwd: Shows your current directory—your GPS in the terminal
  • cd: Changes directory—use Tab completion religiously to save typing
  • ls: Lists directory contents—master -l, -a, -h, -t, -S options
  • Wildcards: * (any characters), ? (one character), [abc] (character set) match multiple files
  • tree: Visualizes directory structure (install separately)
  • file: Identifies file types by content, not extension
  • stat: Shows detailed file metadata

Practice these commands daily. Navigation becomes muscle memory quickly, and soon you'll be flying through directories faster than any GUI file manager could take you.

In the next tutorial, you'll learn to actually do things with files—create, copy, move, delete, and manage permissions.

Was this page helpful?
SR

Written by the ShellRAG Team

The ShellRAG editorial team writes practical, beginner-friendly Bash Shell tutorials with tested code examples and real-world use cases. Every article is technically reviewed for accuracy and updated regularly.

Learn more about us →