ext4 allows certain chars in filenames which NTFS doesn't. Is there a script to replace those chars in filenames?
2 Answers
The following should replace all disallowed characters in filenames with underscores. Note that this may cause multiple files to be renamed to the same thing. For example, if you had two files called file>/txt
and file<.txt
, both will be renamed to file_.txt
, and one will overwrite the other, deleting it.
find /path/to/ntfs/mount/ -print0 | xargs -0 rename 's{[\\:*?"<>|]}{_}g'
This command is valid for the perl version of rename, which is what Debian provides. Your distro may provide a version of rename with a slightly different syntax.
-
2This syntax is only valid for
perl-rename
, which ships asrename
on Debian. Other distros come with a simplerrename
from util-linux. May 7, 2011 at 23:31 -
Also, 1) do not replace
/
, because this would affect legitimate path separators; 2) theg
option is needed to match all characters, not just the first occurence. May 7, 2011 at 23:34
First I must note that NTFS supports the full POSIX namespace so file names on it can contain any characters except /
and '\0'
just like ext4. Only the Win32 namespace forbids some more characters and uses case-insensitive name lookups. In the past there were various Unix subsystems in Windows and nowadays there are WSL and WSL2 so you can freely store any kinds of Linux filenames on NTFS
So now in order to operate properly with apps that use the Win32 namespace you need to fix the names. But it's a bad idea to replace all the forbidden characters with _
. There are so many good replacement characters in Unicode that you can use, for example just convert the characters from the half-width to their full-width form. With perl-rename
you can do this with the tr
command
find /mount/point -print0 | xargs -0 \
rename 'use utf8; use open qw/:std :utf8/; tr#\\:*?"<>|#\:*?"<>#'
If you want to limit to ASCII only then you can find some character with the similar meaning to replace, for example translating "
to '
find /mount/point -print0 | xargs -0 rename 'tr#\\:*?"<>|#_\-._'"'"'[]!#'
Some more suggestions that you can choose for a better replacement string
\
: 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:¦‖∣│।ǀ
pathchk
may help. It doesn't do the conversion, but should tell you if a file needs converting.