How can I batch rename file names so that they do not include characters that clash with other file systems as for instance,
Screenshot 2015-09-07-25:10:10
Note that the colons are the issue in this file name. These will not be digested by Windows or Mac.
These files could be renamed to
Screenshot 2015-09-07-25--10--10
I have to move a large amount of files from Ubuntu to another OS. I copied them to an NTFS drive using Rsync, but that lost some files. I also copied them to an ext4 drive.
The following list are the reserved characters:
< (less than)
> (greater than)
: (colon)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
Another issue is that Windows is not case-sensitive when it comes to file names, (and most OS X systems as well).
You could do something like:
This will replace all these characters with a
_
. Note that you need not to replace/
, since it's an invalid character for filenames in both filesystems, but is used as the Unix path separator. Extend to a directory and all its contents with:Note that both
/
(which marks the end of the pattern) and\
are escaped. To retain uniqueness, you could append a random prefix to it:A more complete solution should, at least:
That's to say,
foo.mp3
should not becomefoo.mp3.1
, butfoo.1.mp3
, since Windows is more reliant on extensions.With that in mind, I wrote the following script. I tried to be non-destructive, by using a prefix path into which I can copy the renamed files, instead of modifying the original.
In action:
The script is available in my Github repo.
Recursively replace a list of strings or characters in filenames by other strings or characters
The script below can be used to replace a list of strings or characters, possibly occurring in a file's name, by an arbitrary replacement per string. Since the script only renames the file itself (not the path), there is no risk of messing with directories.
The replacement is defined in the list:
chars
(see further below). It is possible to give each string its own replacement, to be able to reverse the renaming if you'd ever want to do that. (assuming the replacement is a unique string). In case you'd like to replace all problematic strings by an underscore, simply define the list like:Dupes
To prevent duplicated names, the script first creates the "new" name. It then checks if a similarly named file already exists in the same directory. If so, it creates a new name, preceded by
dupe_1
ordupe_2
, until it finds an "available" new name for the file:becomes:
The script
How to use
rename_chars.py
.Test- run it on a directory by the command:
Note
Note that in the line:
in python, a backslash needs to be escaped by another backslash.
I think the above solutions might work, but you have another case: ext filesystem allows longer filenames and folder names. You also have to consider the length of the names and trunk them using some algorithm, adding numbers or something in the end in the case of duplicate names.