Super User is a question and answer site for computer enthusiasts and power users. 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

Im trying to move files into subfolders based on a regular expression. For example im trying to move tv shows into the correct show and season folder. All files follow the pattern "Show Name.S00E00.episode title.avi".

I've looked at mmv and rename but can't seem to find any helpful examples.

If someone could point me in the right direction I would be very grateful.

Edit: I forgot to mention the folder structure is

   Unsorted video files 
   Show Name/
      Season 1/
           Video Files Sorted
      Season 2/
share|improve this question
up vote 3 down vote accepted

For the bash shell:

for file in *.avi; do
    # use perl to transform the file name; could use 'sed -r' too
    new_path=$(perl -pe 's|^(.+?)\.S0*(\d+)E0*(\d+)\.(.+)\.(\w+)$|$1/Season $2/Episode $3 - $4.$5|' <<< "$file")
    # create directories if needed
    mkdir -p "${new_path%/*}"
    # move the file
    mv -vn "$file" "$new_path"

In this regexp example (s|...|...|):

  • $1 is the show name (everything up to ".S<num>E<num>");
  • $2 and $3 are season/episode numbers;
  • $4 is the episode title (everything up to the final ".");
  • $5 is the file extension.

If you want to keep leading zeroes in season/episode numbers, replace S0* and E0* with just S and E. If you want to process other file types, adjust *.avi in the first line.

Debian and Ubuntu come with a Perl-based prename script which could be used for this, but it doesn't create the new directories automatically. It's easy to modify it to do so; then you can just use prename 'the above regexp' *.avi.)

share|improve this answer
Can you explain why (.+?) for season name, why not just (.+) – bbaja42 Jun 11 '11 at 11:02
That worked perfectly. Thank you! :D – AverageMarcus Jun 11 '11 at 11:31
@bbaja42 .+? is non-greedy, meaning it will match as little as possible. – Tyilo Aug 7 '12 at 16:30
@Tyilo, thanks for the clarification. – bbaja42 Aug 7 '12 at 20:29

Or you can use only bash commands all the way (if all your files really follow the structure you've provided):

for episode in *avi ; do
  ### cut $episode into fields, separated by "." and assign the first such field to $showname
  ### assign the second and third character of the second field to $season
  showname=`echo $episode | cut -d "." -f1`
  season=`echo $episode | cut -d "." -f2 | cut -c 2,3`
  ### create directory only if not already created
  mkdir -p $showname/$season
  ### move the file
  mv $episode $showname/$season/
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .