I regularly copy files onto USB sticks or SD cards that are formatted with FAT32. And every time there is trouble with file names that contain characters FAT32 does not allow. Colons, question marks, asterisks, everything that is completely normal under Linux becomes a problem on FAT32.
So I wrote myself a Bash script that takes care of the work. It searches the current folder, replaces all invalid characters, and also takes care of leading or trailing spaces and dots. Collisions are avoided by appending a counter.
What the Script Does
The script works in several steps. First, all files in the current folder are iterated through. For each file, the name is checked and cleaned up.
The characters forbidden by FAT32 are the backslash, the slash, the colon, the asterisk, the question mark, the quotation marks, the angle brackets, and the pipe. All of these characters are replaced by an underscore.
In addition, control characters are removed, i.e., characters with the codes 0x00 to 0x1F. They rarely appear, but when they do, they cause problems.
Then leading and trailing spaces and dots are removed. FAT32 does not like that, even if it is not a problem on other file systems.
If the name is empty after that, an emergency name is assigned.
And finally, it is checked whether a file with the new name already exists. If so, a counter is appended to avoid collisions.
How to Use It
Save the script in the folder where you want to use it under a name such as fat32-rename.sh and start it
bash fat32-rename.sh
The script only works in the current folder. Subfolders are not searched. If you also want to clean up subfolders, you would have to combine it with find or write a recursive variant.
What You Should Keep in Mind
The script renames files. If you want to make sure that nothing goes wrong, you should make a backup beforehand or at least test what the script would do before you unleash it on important data.
The script does not overwrite files. If a file with the new name already exists, a counter is appended so that the new name is unique.
The script only processes files, not folders. If you also want to rename folders, you would have to adjust the condition [ -f "$f" ] accordingly.
Conclusion
The script has already saved me a lot of time. Instead of renaming files individually, I simply let it run over the folder and afterwards I copy the files onto the FAT32 storage medium. This works reliably and I no longer have to worry about invalid characters.
If you frequently deal with FAT32, this is a small helper that quickly pays for itself.
The Script
#!/usr/bin/env bash
# Replaces FAT32-invalid characters in file names in the current folder
# Author: hoergen
# 15.09.2026
for f in *; do
[ -f "$f" ] || continue
# Replace FAT32-forbidden characters:
# \ / : * ? " < > | -> _
# Additionally remove: control characters (0x00-0x1F) at the beginning/end
new=$(echo "$f" \
| tr '\\/:*?"<>|' '_________' \
| tr -d '\000-\037')
# Remove leading/trailing spaces and dots
# (FAT32 does not like that)
new=$(echo "$new" | sed -e 's/^[ .]*//' -e 's/[ .]*$//')
# Empty name -> emergency name
[ -z "$new" ] && new="unnamed"
if [ "$f" != "$new" ]; then
# Avoid collisions
if [ -e "$new" ]; then
base="${new%.*}"
ext="${new##*.}"
[ "$base" = "$ext" ] && ext=""
n=1
while [ -e "${base}_$n${ext:+.$ext}" ]; do
n=$((n+1))
done
new="${base}_$n${ext:+.$ext}"
fi
mv -- "$f" "$new"
echo "OK $f -> $new"
fi
done