Converting filenames to Title Case in Linux

by @edent | # # | 8 comments | Read ~768 times.

Here's a simple bash one-liner to convert mixed-case filenames into Title Case:

rename 's/(\S+)/\u\L$1/g' *

This forces the file extension to lower-case as well.

Use rename -n to test the command without changing anything on the filesystem.

(Adapted from this PerlMonks FAQ.)

Background

I have a bunch of inconsistently named files like:

HERE COMES THE SUN.mp3
hey jude.mp3
The lOng and wiNDing Road.mp3

I want them to appear as:

Here Comes The Sun.mp3
Hey Jude.mp3
The Long And Winding Road.mp3

Two Line Approach

First, rename all files to lower-case:

rename 'y/A-Z/a-z/' *

Second, make the first letter of each word Upper Case:

rename 's/(^|[\s_-])([a-z])/$1\u$2/g' *

Support this blog

Enjoyed this blog post? You can say thanks to the author in the following ways:

Donate to charity
Give to charity.
Buy me a birthday present
Amazon Wishlist
Get me a coffee
Donate on Ko-Fi.

8 thoughts on “Converting filenames to Title Case in Linux

  1. mike says:

    You didn't remove the spaces! What sort of monster are you!? 😉

    I like the rename command though. Years of poking around *nix and I didn't recall ever encountering it. I would have used to mv and an argument involving tr to convert lowercase.

    $ echo "The lOng and wiNDing Road.mp3" | tr [:upper:] [:lower:]
    the long and winding road.mp3

  2. Exceptions of course ...
    Old MacDonald Had A Farm
    and for fun ... try one towards the end of
    http://www.dandelionradio.com/tracklists/2012-01/

    I was discussing same sort of thing recently - see posts about 5 down
    http://forums.slimdevices.com/archive/index.php/t-106900.html

    1. Terence Eden says:

      Yes, tricky with non-ASCII characters.

  3. Heretic! That should be:

    Here Comes the Sun.mp3
    Hey Jude.mp3
    The Long and Winding Road.mp3

    Friendships have ended over less 😉

  4. Arthur says:
    #!/bin/bash
    
    for file in * ; do
        words=("$file")
        title=""
        wc=0
        for word in $words ; do
        first=$(echo $word | cut -c1 | tr ‘[[:lower:]]’ ‘[[:upper:]]’)
        others=$(echo $word | cut -c2-)
        word="$first$others"
        for prep in {The,A,An,As,At,But,By,For,In,Of,Off,On,Per,To,Up,Via,And,Nor,Or,So,Yet,With}
        do
            if [[ $wc -gt 0 ]] ; then
            if [[ "$word" == "$prep" ]] ; then
                word=`echo "$word" | tr '[A-Z]' '[a-z]'`
            fi
            fi
        done
        title="$title$word"
        title="$title "
        wc=$(($wc + 1))
        done
        #echo "$title"
        mv -- "$file" "$title" > /dev/null 2>&1
    done
    

    One thing it DOES NOT do is capitalize last word if it is a preposition which seems to be the rule in all three title case schools (Chicago, MLA and AP), but this does the job in probably 95%~99% cases.

  5. Adrian says:

    One line approach 🙂

    rename -E 'y/A-Z/a-z/' -E 's/(^|[\s_-])([a-z])/$1\u$2/g' *

  6. jamisan says:

    elegant and simple. reminds me of an old unix bud of mine (god rest his soul). he said, i just love when I can write a one line program with a string of text and a couple of alt-shift-left-elbows. thanks terence. p.s. how can i find if you have other similar gems buried in your blogs?

    1. @edent says:

      Thanks! You'll find most of them at https://shkspr.mobi/blog/tag/linux/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.