I need an assist here, got a project going where we need to modify file & folder names within a specific directory in order to remove or replace any and all characters which would be considered illegal under Windows, with a few additional characters. Leave final extnsion


    < (less than)                         MAKE -
    > (greater than)                      MAKE -
    : (colon)                             MAKE -
    " (double quote)                      REMOVE
    / (forward slash)                     MAKE -
    \ (backslash)                         MAKE -
    | (vertical bar or pipe)              MAKE -
    ? (question mark)                     REMOVE
    * (asterisk)                          REMOVE


    REMOVE '
    REMOVE %
    REMOVE #
    REMOVE ^
    REMOVE !@#$%^&()=+][{};,`~

Any character with "MAKE -" next to it needs to be made a - (hyphen) in place of the character, for example a file named John\Sykes.doc needs to become John-Sykes.doc. If the character is flagged as "REMOVE" then it should be removed, and nothing be put in it's place, for example a file named John?Sykes.doc would become JohnSykes.doc

This is a rather important step in a very large project we have going in our organisation, and I haven't been able to create a script thus far. I know how to make simple versions, that can only change file names on a case by case basis but can't do it en mass. For example, I can create a script to remove only @ from file names, but I don't know how to include folders/directories nor do I know how to include all the other characters in this one script.

Ideally the script would run the first time and produce a file using echo with all the changes that need to be made including the full path and then the changed path. The script would then either need to be modified slightly to use mv instead, or it could refer to the file created using echo and perform all the necessary changes using it...

Any and all help would be appreciated as this is really rather important and I lack the skills at this point in time to make this myself...

A final note, I can't use the #rename command. It breaks our IT policy.


I'm unable to use any version of rename, the head of my IT dept. has forbade it. I'm sure he has his reasons, but I can't say that I'm privy to them. The rename command is not available on our servers at all.

This means I have to use pure bash to perform the operation.

There aren't any additional requirements. Basically I need to be able to run a script to output all the changes that will be made to a file, before anything is changed. This will allow us to review the results and make sure there are no stuff-ups. After that, we want to run (the same script or a different one) it to actually make the changes.

All I need is stated above, so anything marked "MAKE -" needs to become a hyphen and anything marked "REMOVE" needs to just go away.

If there's anything else, please ask. I'll happily give further comment.

  • 2
    You say that the rename command "breaks our IT policy". What do you mean? Does the solution have to meet any additional requirements like the language it's written in or the used commands? – Byte Commander Nov 16 '15 at 14:48
  • Please also clarify which version of rename you're referring to (Perl's rename?), and also which other requirements you have, if any. For example are Perl / AWK ok? Are you tied to use pure Bash only? – kos Nov 16 '15 at 14:52
  • What about rename.ul? Is that allowed? And would it not be easier to copy all the files over to a desktop and do it there? Otherwise I would tell that IT person to do it himself ( :) ) – Rinzwind Nov 16 '15 at 15:30
  • Nah, I'm afraid not, has to be pure bash. He'll only allow for it. And he's my boss, haha! Wish I had the authority to tell him to do it himself, but hey... this is a learning experience for me so I'm grateful for it. I'm busy specializing in linux but admittedly I'm far from an expert as yet, so I appreciate when I get a chance to broaden my knowledge. – Ludicael Nov 16 '15 at 15:46
  • Let's continue the discussion under my answer here, since that answer is potentially harmful and needs to be deleted. Do you need to perform this recursively or on a single directory? – kos Nov 16 '15 at 15:55

Create a script rename1.sh:

#! /bin/bash
new=${new//['<>:\|']/-}                   # I removed /, see below.
if [[ -e $new ]] ; then
    if [[ $old != $new ]] ; then
        echo Cannot rename "$old" to "$new" - target already exists.
    mv "$old" "$new"

It renames one file according to the given rules using parameter expansion. To rename a subtree, run it with find:

find /path -exec rename1.sh {} \;

Are you sure you want to replace / with -? It would put all the files into the same directory.

  • Thank you, I'm going to test this now and reply with the results – Ludicael Nov 16 '15 at 15:08
  • For safety, you might first run it with echo mv instead of mv to check the output. – choroba Nov 16 '15 at 15:10
  • That's exactly what I'm going to do. Your help is much appreciated. I'm busy making a test directory with a bunch of meaningless files for a test bed too. – Ludicael Nov 16 '15 at 15:16
  • $find ./TEST/ -exec rename1.sh {} \; find: rename1.sh: no such file or directory (x6) there are 6 files in the directory and I'm getting that error 6 times, is it related? – Ludicael Nov 16 '15 at 15:27
  • Nevermind, I made a typo, it's working.... THANK YOU <3 – Ludicael Nov 16 '15 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.