Search code examples
bashmacoscamelcasing

Convert folder and file names to camel case


I have a list of folders and files whose names contain spaces. How can I change the names into camel case?

for oldname in *
do
  newname=`echo $oldname | sed -e 's/ /_/g'`
  if [ "$newname" = "$oldname" ]
  then
    continue
  fi
  if [ -e "$newname" ]
  then
    echo Skipping "$oldname", because "$newname" exists
  else
    mv "$oldname" "$newname"
  fi
done 

I have found this but it changes the spaces into underscores.


Solution

  • You can use the regular expression aptitude to deal with upper and lower case translations, regarding your current local collation (LC_ALL, check with the locale command).

    If your filename's "words" are separated with a space and are all in lower case, you can use a simple shell script like this :

    #!/bin/sh
    while read -r FILENAME ; do
      NEWNAME="`echo \"${FILENAME}\" | sed 's/  *\([^ ]\)/\u\1/g'`"
      if [ ! "${NEWNAME}" ] ; then
        NEWNAME="${FILENAME}";
      fi
      if [ "${FILENAME}" = "${NEWNAME}" ]; then
        printf "No change : %s\\n" "${FILENAME}" >&2;
      else
        if [ -e "${NEWNAME}" ] ; then
          printf "Already changed : %s => %s\\n" "${FILENAME}" "${NEWNAME}" >&2;
        else
          echo "mv \"${FILENAME}\" \"${NEWNAME}\"";
        fi
      fi
    done
    

    Remove the echo on echo "mv \"${FILENAME}\" \"${NEWNAME}\""; to do the mv.

    Note that it should work fine with accented letters or any unicode letter having lower and upper code.

    The script takes the file list to operate from stdin, so to use it "as is", you can use something like the following examples :

    • find . -type 'f' | theScript.sh

      For a whole tree of files. For folders, you'll have to operate them separately. List them and sort them in a descending order.

    • ls -1 | theScript.sh

      For files in the current folder.

    If your files may have all or partial upper cases at start and you look to force them entirely to camel case, you can change the line :

      NEWNAME="`echo \"${FILENAME}\" | sed 's/  *\([^ ]\)/\u\1/g'`"
    

    With:

      NEWNAME="\`echo \"${FILENAME}\" | sed 's/\(.*\)/\l\1/;s/  *\([^ ]\)/\u\1/g'\`"