Score:2

How to rename multiple files and folders recursively that include * and other symbols not valid for filenames/folders?

mu flag

For somewhat reason, my Ubuntu Mate 20.04 let me include * and other symbols apparently not valid for a filename or folder. But now I need to copy a lot of archives (like 15,000) to another PC. I don't know how to make a script for this, so I need help with it to let me rename everything inside a folder and the name of that folder also, example:

Folders:

701*math**2nd

100*eng**1st

etc...

Archives:

800-task**201.xls

508-ok*10**300.doc

etc...

I just need to remove the characters, exchanging the * for a _ or just remove the character from the name of file, because file manager doesn't let me copy them to an external HDD.

**EDIT: This worked! https://askubuntu.com/a/1302061/1661703

FedKad avatar
cn flag
`*` is a perfectly valid character for file names (if you are using EXTx file system format). The _only_ invalid characters are `/` and NUL. However, if you are trying to store files with `*` and other special characters not valid on an NTFS file system, then you have to replace these. For more info see this: https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
Silver avatar
mu flag
I didnt know that, so in this case I need to remove these characters so I can copy them to a NTFS filesystem
FedKad avatar
cn flag
If your external disk is just empty (that is, it will be used only to transfer files) *and* your target PC is also Linux, I would recommend formatting your external disk as EXT4 (and *not* NTFS or some variant of FAT).
Silver avatar
mu flag
I need to transfer those files to a windows Pc, so I still need to convert them
Silver avatar
mu flag
This worked: https://askubuntu.com/a/1302061/1661703
pierrely avatar
cn flag
you could install Krusader with Krename, Tools, Search , save to listbox, then File, Multirename, Find and Replace, Add , * to _ ... what I cannot do is search, or filter the results, for only files with an * in them, though if all satisfy that, then select all to krenam, or select manually. one advantage here is being able to see the renames before applying them.
Score:0
jp flag

You can use the rename command with recursive shell globbing from the parent directory containing all your directories and files that you need to be renamed like so:

shopt -s globstar
rename -n 'y/\*/_/' **/*
shopt -u globstar

Or (to avoid a Argument list is too long error) with find and rename from the same parent directory like so:

find -exec rename -n 'y/\*/_/' {} \+

The option -n is for dry-run … Remove it when satisfied with the output to do the actual renaming.

Additional raname syntax:

  • To change each multiple sequence of *(e.g. ** or *** etc.) to a single _, use:

    rename -n 's/[\*]+/_/g'
    
  • To match and substitute multiple different characters(e.g. *, ? and : etc.), use:

    rename -n 's/[\*\?\:]+/_/g'
    
  • To just remove the matching characters from the names, use empty substitution string like so:

    rename -n 's/[\*\?\:]+//g'
    

Notices:

  • Please notice that due to directories being renamed as well(if their names contain matching charackters e.g. *, ? or : etc.), some file paths already passed to rename as arguments might change during the process which will result in the error:

    Can't rename ...: No such file or directory
    

    preventing them from being renamed all at once so you need tor re-run the rename command until you get no errors anymore.

  • Please also notice that if two or more similar file/directory names share the same path and match different matching characters(e.g. file**one, file??one and file:one etc) then they will all be renamed to the same filename(e.g. file_one*) resulting in only the first name of its kind(*file/directory`) being renamed and the others will result in the error:

     ... not renamed: ... already exists
    

    Therefore, in which case you will need to change the substitution character/s in the rename command in order to rename those remaining files/directories e.g. double _ like so:

    rename -n 's/[\*\?\:]+/__/g'
    
Silver avatar
mu flag
I get an error: "Argument list is too long"
Raffa avatar
jp flag
@Silver I updated the answer for that.
Raffa avatar
jp flag
@Silver I apologize ... There was an unintended mistake(*typo*) in the answer but now corrected ... I apologize again :-)
FedKad avatar
cn flag
The rename operation is a risky one. There is always a chance of name collision, because NTFS is case sensitive and you have to map more than one (forbidden) characters onto a single (`_`) character. Windows has also name restrictions on complete file / directory names.
Raffa avatar
jp flag
@FedKad Thank you for your feedback :-) Added your notes to the answer ... unfortunately as you know such a process can not simply and cleanly be done in one shot.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.