Creating directory name from file name - strip out non alpha numeric characters and make lower case

I am able to create a directory based on the name of a file. I am running into a wall if the text has spaces or non alpha numeric characters. I would like to strip out those non alpha numeric characters and turn what is left into lower case. This will make the name of the directory. I tried running a few test but I am not even able to strip out the spaces.

Also could I limit to 25 characters?

    __FILE_NAME="Test File@#!!.txt"
    echo ${__FILE_NAME// /_}
    $ echo $__FILE_NAME | tr '[:upper:]' '[:lower:]'
    mkdir -p $__PATH${__FILE_NAME};

Solution 1:

Using bash:

f="Test File@#!!.txt"
f="${f// /_}"
f="${f//[^[:alnum:].]/}"
f="${f,,?}"
mkdir -p "$__PATH$f"

Explanation:

  • f="${f// /_}"

    This replaces all spaces with underlines. The use of double-quotes here is optional. Until one becomes skilled in the shell's many special cases, however, it is good practice to put them in everywhere a variable is used.

  • f="${f//[^[:alnum:].]/}"

    This uses another of bash's parameter expansions to strip out all non-alphanumeric characters except for periods. (I was guessing that you might want to keep them.)

    If you want to strip out periods also, replace this line with:

    `f="${f//[^[:alnum:]]/}"`
    
  • f="${f,,?}"

    tr is the traditional tool converting upper case to lower case. This line instead uses one of bash's built-in parameter expansion to do the conversion.

  • mkdir -p "$__PATH$f"

    Unless one wants the shell to process the shell variables, it is safer to put them in double-quotes.