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.