6

I'm having trouble figuring an mmv pattern. I have a bunch of video files with this pattern:

my.program.name.season.NN.episode.NN.-.title.avi

and I need to move them to:

my.program.name.sNNeNN.title.avi

I can't seem to get the right pattern...

  • 1
    Doesn't mmv 'my.program.name.season.*.episode.*.-.*.avi' 'my.program.name.s#1e#2.#3.avi' work? – Stéphane Chazelas Dec 17 '14 at 10:42
5

TL;DR

rename -n 's/^((\w+\.+){3})(.).*\.(.*)\.(.).*\.(.*)\.\-(\..*)$/$1$3$4$5$6$7/' *
  • \w+ matches one or more word characters, i.e. [a-zA-Z0-9_]+ [1]
  • \.+ matches one or more dot(.) character [2]

    Note that \. matches the . character. We need to use \. to represent . as . has special meaning in regex. The \ is known as the escape code, which restore the original literal meaning of the following character.

  • (\w+\.+){3} matches maximum 3 times of any accuracies of above [1],[2] group of characters starting from beginning(^ matches the beginning of names) of the files name.
    This will match or return my.program.name.

    Note that extra parentheses around the regex is used for grouping of matching. Grouping match starts with ( and ends with ) and used to provide the so called back-references. A back-reference contains the matched sub-string stored in special variables $1, $2,, $9, where $1 contains the substring matched the first pair of parentheses, and so on.

  • . The metacharacter dot (.) matches any single character. For example ... matches any 3 characters. so with this (.) we are matching the first character of season which it is s.

  • .*\. matches everything after a single char in above until first . if seen. As you can see we didn't capture it as group of matches because we want to remove that from our name, where this matches eason..

  • (.*) matches everything after above match. This matches NN. Parentheses used here because we want to keep that in file name.

  • \. matches a single dot after above match. A . after first NN.

  • (.) again with this one we are matching the first single character after above match. this will return only e.

  • .*\. will match everything after above match until first .. Will match pisode..

  • (.*) matches anything after last matched dot from above match. This will match second NN.

  • \.\- matches a dot. followed by a dash-. Will match or return .-

  • And finally (\..*)$ matches a single dot. and everything after that which ends to end of the file name. $ matches the end of the file name or input string.

Note: remove -n option to perform actual renaming.

1

You can make it pure BASH:

netikras@netikras-netbook /tmp $ ls -l /tmp/*.*season.*episode.*avi
-rw-r--r-- 1 netikras netikras 0 Grd 16 10:29 /tmp/my.program.name.season.05.episode.07.-.title.avi
-rw-r--r-- 1 netikras netikras 0 Grd 16 10:29 /tmp/my.program.name.season.05.episode.32.-.title.avi
-rw-r--r-- 1 netikras netikras 0 Grd 16 10:29 /tmp/my.program.name.season.05.episode.35.-.title.avi
-rw-r--r-- 1 netikras netikras 0 Grd 16 10:29 /tmp/my.program.name.season.NN.episode.NN.-.title.avi

netikras@netikras-netbook /tmp $ for i in *.*season.*episode.*avi; do nn="${i/season./s}"; nn=${nn/.episode./e}; nn=${nn/.-./.}  ; echo "moving: $i ----> $nn"; mv $i $nn; done
moving: my.program.name.season.05.episode.07.-.title.avi ----> my.program.name.s05e07.title.avi
moving: my.program.name.season.05.episode.32.-.title.avi ----> my.program.name.s05e32.title.avi
moving: my.program.name.season.05.episode.35.-.title.avi ----> my.program.name.s05e35.title.avi
moving: my.program.name.season.NN.episode.NN.-.title.avi ----> my.program.name.sNNeNN.title.avi

This way you do not have to call any external applications, i.e sed/awk, to do the job. BASH can easily modify strings with built-in tools. You just replace 3 parts of your filename and create a new one. Then all what's left is to assign the new name to the file. No need to learn any of those spooky looking regexes to do simple job.

0

Try doing this with perl's rename :

rename -n 's/
            (.*?s)eason\.(\d{2})\.episode\.(\d{2})\.-\.(.*\.avi)
            /$1$2e$3.$4/x
' my.program.name*

Once you are satisfied that this does what you want, remove the -n to actually perform the renaming.

  • @Jocala: The -n option inhibits the actual renaming operation, it just displays what files would be changed, and what they would be changed to. When run without an option rename does its work silently; supply a -v option for verbose mode, i.e., the same output in the terminal as with the -n option, but the files do actually get renamed. – PM 2Ring Dec 16 '14 at 4:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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