How to Rename Any File Extension to Lowercase on macOS or Linux

If you work with files from multiple operating systems, digital cameras, Windows PCs, scanners, or network storage devices, you’ve probably encountered files with uppercase extensions like:

PHOTO.JPG
DOCUMENT.PDF
LOGFILE.TXT
SPREADSHEET.XLSX

While Windows generally ignores the case of filenames, Linux, web servers, and many automation tools often treat filenames exactly as written. A mixture of uppercase and lowercase extensions can cause problems with websites, scripts, media libraries, and backup software.

Fortunately, Bash provides a quick and reliable way to standardize your files.

In this article, you’ll learn several methods—from simple one-line commands to a reusable Bash script—that safely convert any uppercase file extension to lowercase.


Why Lowercase Extensions Matter

Standardizing file extensions provides several benefits:

  • Consistent filenames across your system
  • Better compatibility with Linux and Unix applications
  • Prevents broken image and document links on web servers
  • Easier scripting and automation
  • Cleaner photo and document archives
  • Better interoperability between Windows, macOS, Linux, and NAS devices

For example:

Before

Vacation.JPG
Taxes.PDF
Resume.DOCX
Audio.MP3

After

Vacation.jpg
Taxes.pdf
Resume.docx
Audio.mp3

Method 1 – Rename One File

Rename a single file:

mv FILE.PDF FILE.pdf

Simple and effective—but impractical for hundreds or thousands of files.


Method 2 – Rename One File Type Recursively

Suppose you only want to rename PDF files.

find . -type f -name "*.PDF" \
-exec sh -c 'mv "$1" "${1%.PDF}.pdf"' _ {} \;

This command:

  • Searches every folder beneath the current directory
  • Finds files ending in .PDF
  • Renames each one to .pdf

Method 3 – Rename Every Uppercase Extension Automatically

Here’s the solution I use most often.

Instead of targeting one extension, it automatically converts whatever extension exists to lowercase.

Examples:

JPG   → jpg
JPEG  → jpeg
PNG   → png
PDF   → pdf
DOCX  → docx
MP3   → mp3
ZIP   → zip
CSV   → csv

No need to know the extensions ahead of time.

Run:

find . -type f | while read -r file
do
    base="${file%.*}"
    ext="${file##*.}"

    if [ "$base" != "$file" ]; then
        lower=$(echo "$ext" | tr '[:upper:]' '[:lower:]')

        if [ "$ext" != "$lower" ]; then
            mv "$file" "$base.$lower"
        fi
    fi
done

How It Works

Let’s break it down.

Find every file

find . -type f

Searches recursively through every subdirectory.


Separate the filename

Vacation.JPG

becomes

Base:
Vacation

Extension:
JPG

using

base="${file%.*}"
ext="${file##*.}"

Convert to lowercase

tr '[:upper:]' '[:lower:]'

changes

PDF

into

pdf

Rename only when necessary

If the extension is already lowercase, nothing happens.

This prevents unnecessary disk operations.


Preview Changes Before Renaming

A good habit is to preview what will happen first.

Replace the mv command with:

echo "$file -> $base.$lower"

You’ll see output similar to:

Vacation.JPG -> Vacation.jpg
Manual.PDF -> Manual.pdf
Audio.MP3 -> Audio.mp3

Once everything looks correct, change echo back to mv.


A Reusable Bash Script

Save the following as:

lowercase_extensions.sh
#!/bin/bash

############################################################
# Lowercase File Extensions
#
# Recursively converts ALL uppercase or mixed-case
# file extensions to lowercase.
#
# Usage:
# ./lowercase_extensions.sh /path/to/folder
#
############################################################

TARGET="${1:-.}"

echo
echo "Scanning:"
echo "$TARGET"
echo

COUNT=0

find "$TARGET" -type f | while read -r file
do
    base="${file%.*}"
    ext="${file##*.}"

    if [[ "$base" != "$file" ]]; then

        lower=$(echo "$ext" | tr '[:upper:]' '[:lower:]')

        if [[ "$ext" != "$lower" ]]; then

            newfile="$base.$lower"

            if [[ -e "$newfile" ]]; then
                echo "Skipped (already exists):"
                echo "  $newfile"
                echo
                continue
            fi

            mv "$file" "$newfile"

            echo "Renamed:"
            echo "  $file"
            echo "  ->"
            echo "  $newfile"
            echo

            COUNT=$((COUNT+1))
        fi
    fi
done

echo
echo "Finished."

Make the Script Executable

chmod +x lowercase_extensions.sh

Run the Script

Current directory:

./lowercase_extensions.sh

Another directory:

./lowercase_extensions.sh ~/Pictures

or

./lowercase_extensions.sh /Volumes/Archive

Handling File Name Conflicts

Suppose both of these files exist:

photo.JPG
photo.jpg

After conversion, both would become:

photo.jpg

The script checks for this condition before renaming and skips the conflicting file instead of overwriting it.

You’ll see a message like:

Skipped (already exists):
photo.jpg

This helps protect your data.


Processing Thousands of Files

The script works well with:

  • Photo collections
  • Music libraries
  • NAS storage
  • WordPress media uploads
  • Web server document roots
  • Backup archives
  • Software repositories

Because it uses the find command, it scales efficiently to very large directory trees.


Bonus: Convert Entire Filenames to Lowercase

If you’d rather make the entire filename lowercase—not just the extension—you can use:

find . -depth | while read -r file
do
    dir=$(dirname "$file")
    name=$(basename "$file")
    lower=$(echo "$name" | tr '[:upper:]' '[:lower:]')

    if [[ "$name" != "$lower" ]]; then
        mv "$file" "$dir/$lower"
    fi
done

Example:

Vacation Photo.JPG

becomes

vacation photo.jpg

Use this option with caution, as it changes filenames in addition to their extensions.


Final Thoughts

Renaming file extensions to lowercase may seem like a small housekeeping task, but it can prevent countless compatibility issues across operating systems, web servers, scripting environments, and automation workflows.

Whether you’re managing a personal photo library, maintaining a Linux server, deploying a WordPress website, or organizing a shared NAS, standardizing file extensions is a simple best practice that pays dividends over time.

The reusable Bash script in this guide makes the process safe, repeatable, and easy to integrate into your regular maintenance routine.

If you frequently work with large file collections, consider adding this script to your toolbox—you’ll likely use it more often than you think.

Leave a Reply

Your email address will not be published. Required fields are marked *