8

ext4 allows certain chars in filenames which NTFS doesn't. Is there a script to replace those chars in filenames?

1
  • pathchk may help. It doesn't do the conversion, but should tell you if a file needs converting.
    – Mikel
    May 7, 2011 at 6:48

2 Answers 2

3

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.

2
  • 2
    This syntax is only valid for perl-rename, which ships as rename on Debian. Other distros come with a simpler rename from util-linux. May 7, 2011 at 23:31
  • Also, 1) do not replace /, because this would affect legitimate path separators; 2) the g option is needed to match all characters, not just the first occurence. May 7, 2011 at 23:34
0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .