Converting filenames to Title Case in Linux


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' *


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

12 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

    Reply
  2. says:

    Heretic! That should be:

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

    Friendships have ended over less 😉

    Reply
  3. 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.

    Reply
  4. 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?

    Reply
  5. Alan says:

    Hi Guys,

    I used the suggestion from XX above:

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

    This works great, except - it lowercases (if I can invent a word) a letter in the middle of a text string containing numbers such as:

    CoMpany - X01B02 - LETTER.txt

    becomes:

    Company - X01b02 - Letter.txt

    Is there any way top amend that one line command to avoid the 'B' in the middle of the reference getting changed to 'b' so that, instead, it comes out as:

    Company - X01B02 - Letter.txt

    I am guessing we need to look for a letter, not being the first character of a word, sandwiched between two numerals, but by RegExp fu is just not up to it!

    If it helps, we can assume it is only ever a single letter with a numeral immediately left and right of it.

    Thanks,

    Alan.

    Reply
  6. CpILL says:

    The first command doesn't work for me on Ubuntu 18.04 for some reason. Here is what it says for one file:

    0003 BEYOND BAROQUE.mp3 not renamed: 0003 beyond baroque.mp3 already exists

    ?

    Reply
  7. John Tweed says:

    Nobody mentions Roman Numerals !? IV -> IV not Iv etc HENRY III -> Henry III MCMLXIV ? (1964)

    Reply

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">