Linux file names can have some common characters, that are not allowed in NTFS file names. These include: colon :, backslash \, vertical bar |, double quote “, asterisk *, question mark ?, less than sign <, greater than sign >.
There are many posts about how to do it with a difficult to read replacement script. I don’t like these, since as needs change it isn’t easy to modify.
Where do I change the replacement for a < in this script? find /mount/point -print0 | xargs -0 rename 'tr#:*?"<>|#__-.._#'
I think that is too hard to puzzle out. Answer: that is 5 characters after the #, so wait is that a double underscore, and is there a space in there, yikes.
Worse though, is there is no error checking. You could easily have one file overwrite another one that got converted into the same file name when you replaced characters.
https://askubuntu.com/questions/1507422/changing-linux-file-names-to-ntfs-compatible-file-names had a clear script that I could improve.
There are “look alike” characters you can replace with, from https://superuser.com/questions/280299/script-to-convert-ext4-filenames-to-ntfs :
\: Reverse Solidus Operator ⧵ (U+29F5), Big Reverse Solidus ⧹ (U+29F9):: see the colon list:ː˸∶︓﹕*: choose one of the various asterisk symbols like*∗✱﹡*✲⁎٭※✻✺?: check this list:¿⁇⍰❓❔︖﹖�": see the list of quoting symbols, for example “<:﹤≪⋖〈❬⟨〈>:﹥≫⋗〉❭⟩〉|: check vertical bar list:¦‖∣│।ǀ
Here are some changes I made with this script:
./Mel Robbins How to HEAL Anxiety And Form CONFIDENCE As A Habit | Rich Roll Podcast.mp4
to
./Mel Robbins How to HEAL Anxiety And Form CONFIDENCE As A Habit - Rich Roll Podcast.mp4
./The Daily Habits To Live Longer & Happier! - Change Your Life One Tiny Step at a Time | Peter Attia.mp4
to
./The Daily Habits To Live Longer & Happier! - Change Your Life One Tiny Step at a Time - Peter Attia.mp4
./Mel Robbins: "Saying These 2 Words Could Fix Your Anxiety!" (Brand New Trick).mp4
to
./Mel Robbins- _Saying These 2 Words Could Fix Your Anxiety!_ (Brand New Trick).mp4
./NASA's Stunning Discoveries on Jupiter's Largest Moons | Our Solar System's Moons Supercut.mp4
to
./NASA's Stunning Discoveries on Jupiter's Largest Moons - Our Solar System's Moons Supercut.mp4
./Bach - St Matthew Passion / Matthäus Passion BWV 244 (reference recording: Nikolaus Harnoncourt).mp4
to
./Bach - St Matthew Passion / Matthäus Passion BWV 244 (reference recording- Nikolaus Harnoncourt).mp4
./J.S. Bach - Cantata BWV 21 "Ich hatte viel Bekümmernis" (J.S. Bach Foundation).mp4
to
./J.S. Bach - Cantata BWV 21 _Ich hatte viel Bekümmernis_ (J.S. Bach Foundation).mp4
./Vocal tips for opera singers: Joyce DiDonato Masterclass in full (The Royal Opera).mp4
to
./Vocal tips for opera singers- Joyce DiDonato Masterclass in full (The Royal Opera).mp4
./The Savings Expert: “Do Not Buy A House!” Do THIS Instead! - Morgan Housel.mp4
to
./The Savings Expert- “Do Not Buy A House!” Do THIS Instead! - Morgan Housel.mp4
Notice that in the St Matthew Passion, there is a “full-width (double-byte) slash” which is allowed in a file name, unlike the normal keyboard / character. Those aren’t double quotes in The Savings Expert, those are double curved quotes.
I am still going to make more changes, for example I like having the person’s name at the front, e.g. “Morgan Housel the Savings Expert “Do Not Buy A House!” Do THIS Instead.mp4” but these I will have to make by hand.
This is enough that I can backup files to an NTFS drive, readable by a Windows computer.
The Script
Remember, some of these characters are UTF-16 replacements. Copy/paste, don’t type. Or, type most of the script but remember to use your own replacement characters.
#! /bin/bash
# Replace characters in Linux file system names, that don't work in file names on NTFS file systems, with characters that do
# first have to chmod +x filename.sh
# Run with:
# find . -exec ext4-to-ntfs-file-names.sh {} \;
old=$1
new=${1//\:/-} # Replace colons by dashes
new=${new//\\/_} # Replace backslashes by underscores.
new=${new//|/-} # Replace vertical bars aka pipes by dashes.
# new=${new// /-} # Replace spaces by dashes.
new=${new//\"/_} # Replace double quotes with underscores.
new=${new//\*/✲} # Replace asterisks by 'look alike asterisks' ✲, see https://en.wikipedia.org/wiki/Asterisk#Encodings
new=${new//\?/⁈} # Replace question marks with 'question exclamation mark'
new=${new//\</_} # Replace less than signs with underscores.
new=${new//\>/_} # Replace greater than signs with underscores.
if [[ $new = $old ]] ; then # No change, skip this one.
exit
fi
if [[ -e $new ]] ; then
echo "Cannot rename $old, since $new already exists" >&2
else
# mv "$old" "$new"
echo -e "$old \n to \n$new\n"
fi
I commented out the mv statement (what actually moves the file to the new name), for testing. Make sure this looks good for all your files, before you rename them.