Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have files named in the style 02.04.11 DJ Kilbot.mp3 (for several dates) and I want to reformat the name in this manner: DJ Kilbot 2011-02-04.mp3. In other words, the current format is MM.DD.YY DJ-NAME.mp3 and I want to change it to DJ-NAME YYYY-MM-DD.mp3. What's the easiest way to do this, for several year's worth of files?

share|improve this question
Do you have the perl rename ala unix.stackexchange.com/a/254066/117549 ? – Jeff Schaller Jan 11 at 1:39
$ rename --version \ rename from util-linux 2.25.2 on cygwin, will see if it's available in packages. – user394 Jan 11 at 1:40
@JeffSchaller OK, I installed it from here: github.com/mengbo/install/blob/master/cygwin/prename – user394 Jan 11 at 1:44
I tend to use editable dired mode in emacs and define a macro and call it multiple times. – Bibek_G Jan 11 at 1:52
up vote 4 down vote accepted

cd to the directory then run the following (using perl-rename). This is a "dry-run" first.

rename -n 's/^([0-9]{2})\.([0-9]{2})\.([0-9]{2}) (.*)\.mp3$/$4 20$3-$1-$2.mp3/' *
02.04.11 DJ Kilbot.mp3 -> DJ Kilbot 2011-02-04.mp3

If you are happy with the output, then run it for real.

rename 's/^([0-9]{2})\.([0-9]{2})\.([0-9]{2}) (.*)\.mp3$/$4 20$3-$1-$2.mp3/' *


  • rename -n: run a test "dry-run".
  • 's/FOO/BAR/' substitute the regex FOO and replace with BAR.
  • ^([0-9]{2})\.([0-9]{2})\.([0-9]{2}) (.*)\.mp3$: regex to capture. Match the start of the string ^, then three lots of [0-9]{2} (i.e. two consecutive numbers) separated by a dot (\. when escaped). Then a space and (.*)\.mp3$. Parens () capture the contents for use in the replacement.
  • $4 20$3-$1-$2.mp3: replace with the DJ name the fourth capturing group ($4), or (.*) above, then the rest of the string as specified (i.e. the third, first and second groups).
  • *: act on all files in the directory.


This regex has a bit of error checking built in. If you are sure that all files are named consistently, you can simplify it slightly to the following.

rename 's/^(..)\.(..)\.(..) (.*)\.mp3$/$4 20$3-$1-$2.mp3/' *
share|improve this answer
Very good, thank you! : ) – user394 Jan 11 at 2:10
You are welcome. Perl-rename is such a great tool! – Sparhawk Jan 11 at 2:16

Without rename:

for file in *.mp3
  the_date=$(echo "${no_extension}" | cut -d ' ' -f 1)
  dj_part=$(echo "${no_extension}" | cut -d ' ' -f 2-)
  new_file="${dj_part} ${date_part}.mp3"
  mv "${file}" "${new_file}"


  • for file in *.mp3 loops through every file in the current directory that ends with the .mp3 extension
  • ${file%.mp3} strips the .mp3 extension from the end of the file using bash string manipulation
  • $(echo ${no_extension} | cut -d ' ' -f 2-) extracts the date part of the file name by using the cut utility, which can parse character-delimited strings
  • then we change the format of the date by extracting the substrings
  • "${dj_part} ${date_part}.mp3" is just string concatenation of the parts we've built
  • mv "${file}" "${new_file}" renames the file
share|improve this answer
Excellent answer. I would just recommend using printf %s in place of echo, and quoting the variable no_extension when you use it. – Wildcard Jan 11 at 2:38

Assume that the files are named strictly that way.

for file in "*.mp3";do 
  date="${file:0:8}" #get the date in the filename. 
  dj="${file%.mp3}" #strip the extension off the filename. 
  dj="${dj:8}" # get dj name.
  mv -nv $file "$dj $date.mp3" # -n don't overwrite files. 
share|improve this answer
This is nice but it doesn't change the date format : / – user394 Jan 11 at 2:10

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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