How to recursively rename a directory tree to valid Windows filenames?

How to recursively rename a directory tree to valid Windows filenames?

I am trying to copy a number of directories containing MS-DOS games from a Linux to a Windows computer. However, I am getting a [WinError 267] The directory name is invalid.

Here is a listing of a few of these directories:

$ ls -d *:* | sort -R | head
Commander Keen 2: The Earth Explodes/
1942: The Pacific Air War/
Super Solvers: Treasure Galaxy/
Life and Death 2: The Brain/
Deja Vu 2: Lost In Las Vegas/
Hard Drivin' 2: Drive Harder/
RoboMaze 2: The Lobby/
Dune 2: The Building of a Dynasty/
Blake Stone: Planet Strike/
Star Trek: First Contact/

I suspect the : in these directory names are causing this error, because they are invalid characters in Windows filenames.

However, since I cannot guarantee that the : is the only invalid character used, I am looking for a way to recursively rename all files and directories to valid Windows filenames, substituting the invalid characters for valid ones.

What Linux command lets me do this?

答案1

I recommend the rename command. Install via:

sudo apt install rename

rename uses Perl to make powerful replace commands, but in this case a simple regex replace will do - something like:

rename 's/[<>:"\\|\?*]/-/g;' *

The above will replace the characters inside the square brackets with the minus sign. The g means replace all of them, not just the first occurrence. If you want something more complex, you could replace some characters with minus and some with underscores, e.g.: rename 's/[<>:]/-/g; s/["\\|\?*]/_/g;' *

The above will only fix files and directories in the current directory. To recursively fix subdirectories and files too, use find:

find -depth -execdir rename 's/[<>:"\\|\?*]/-/g;' '{}' +

In the above example, find will run rename for every item in or under the current directory, doing a depth-first search.

相关内容