Search code examples
bashloopstrmv

Replace special characters recursively bash


I'm trying to find all files and folders in a certain folder and all sub-folders and replace all special characters. All spaces should be replaced with dots and everything else should just be deleted. I've tried a few different ways but when I use "mv" it doesn't seem to preserve the directory structure and when I use "rename" along with "find" it doesn't want to go recursively.

The closest I've gotten is this:

for f in **/; do mv "$f" `echo $f | tr " " . | tr -dc '[:alnum:].'`; done

But I think the loop is broken somewhere as it adds filenames together and places the result in the parent directory.


Solution

  • You could do:

    find . -depth -execdir rename 's/\s/./g; s/[^[:alnum:]./]//g' {} +
    

    A couple of points here:

    • -depth -- traverse the directory hierarchy depth-first. This ensures that you rename the files in a folder before you rename the folder
    • -execdir -- executes the command in the subdirectory -- {} will now be ./filename instead of ./dir1/dir2/filename
    • this is the perl-flavoured rename, check your man page.