1

im trying to create a bash to automate rename files from, if for an anime:

Example:

[TAG] One Piece - 01 [Quality].mkv

to:

[TAG] One Piece - S01E01 [Quality].mkv

But this isnt always because i follow TheTVDB season and episodes, i was using this scrapper for Plex (https://github.com/ZeroQI/Absolute-Series-Scanner) but know im using Emby and need to be renamed following TheTVDB format.

Another example:

[TAG] One Piece - 872  [Quality].mkv

to:

[TAG] One Piece - S19E93 [Quality].mkv

Edited, because first time i didnt explain weel.

To sum up i want to do something like the scrapper but renaming files if possible.

  • 1
    How do you know that [TAG] Anime Name - 01 [Quality].mkv is season 1 and episode 1? Also are [TAG] and [Quality] literally inside brackets? Can you give an actual example of both formats? – Jesse_b Feb 15 at 14:12
  • For example: If its: 870, S08E70 – Vinanrra Feb 15 at 16:44
  • That didn't clarify anything. Please tell me how you identify files with a number less than 100. Also please address my other concerns. – Jesse_b Feb 15 at 16:46
  • [TAG] and [Quality] are always inside brackets and who i know 01 its season 1 and episode 1 i use TheTvdb to know which season and chapter its each one depending of chapter number Example: Number 872 is S19E93 So i totally fucked this and i dont know how to handle that, but i think with ur bash i can modify little thing and change each season. – Vinanrra Feb 15 at 17:04
  • I changed first post i think now i explained batter – Vinanrra Feb 15 at 17:27
0

Assumptions:

  1. Files to be renamed are all of the form [<tag>] <name> - <serial> [<quality>].mkv.
  2. Each anime has a lookup file called <name>.lst, listing the episodes in serial order, e.g. One Piece.lst contains:

    S01E01
    S01E02
    ...
    S01E08
    S02E01
    ...
    
  3. You use a bash shell at version 4 (minimum).

Here's the script to canonicalize your anime vids:

#!/bin/bash
# USAGE: canon_vids <dir> ...
# Canonicalize the filenames of all MKV vids in each <dir>

# All the anime lookup tables are in the lookup subdirectory
# where canon_vids is stored
lookup_dir="$(dirname "$0")/lookup"

log_skip() {
  echo "SKIP ($1): $2"
}

find "$@" -name \*.mkv | while read f; do
  # Check filename against our desired pattern
  # (We don't want to rename what's already been renamed!)
  if [[ $f =~ /(\[[^]]+\])\ (.*)\ -\ ([0-9]+)\ (\[[^]]+\].mkv) ]]; then
    # We've now split our filename into:
    prefix="${BASH_REMATCH[1]}"
    name="${BASH_REMATCH[2]}"
    serial="${BASH_REMATCH[3]##0}"
    suffix="${BASH_REMATCH[4]}"
    # Some sanity checks
    if (( serial <= 0 )); then
      log_skip "$f" "Invalid serial# '$serial' for $name"; continue
    fi
    # Let's look up the episode
    episode="$(sed -n ${serial}p "$lookup_dir/${name}.lst")"
    if [[ -z "$episode" ]]; then
      log_skip "$f" "Can't find serial# '$serial' for $name"; continue
    fi
    mv -vn "$f" "${f%/*}/${prefix} ${name} - ${episode} ${suffix}"
  fi
done

And here's a bonus script that generates those lookup files, given the number of episodes in each season:

#!/bin/bash
# USAGE: generate_series <#eps> ...
while [[ $1 ]]; do
  ((s++))
  for e in $(seq "$1"); do
    printf "S%02dE%02d\n" $s $e
  done
  shift
done

And to test it all:

$ ls
canon_vids  generate_series

# Create One Piece lookup table
$ mkdir lookup
$ ./generate_series 8 22 17 13 9 22 39 13 52 31 99 56 100 35 62 49 118 33 96 > lookup/One\ Piece.lst
$ tail -n lookup/One\ Piece.lst
S19E92
S19E93
S19E94
S19E95
S19E96
$ wc -l lookup/One\ Piece.lst 
874 lookup/One Piece.lst

# Create fake One Piece MKVs (adding a couple more to trigger errors)
$ mkdir op
$ for i in $(seq 0 876); do touch "$(printf "op/[TAG] One Piece - %02d [quality].mkv" $i)"; done
$ ls op | wc -l
877

# And now, the moment of truth...
$ ./canon_vids op
renamed 'op/[TAG] One Piece - 724 [quality].mkv' -> 'op/[TAG] One Piece - S17E97 [quality].mkv'
renamed 'op/[TAG] One Piece - 86 [quality].mkv' -> 'op/[TAG] One Piece - S06E17 [quality].mkv'
...
renamed 'op/[TAG] One Piece - 819 [quality].mkv' -> 'op/[TAG] One Piece - S19E41 [quality].mkv'
SKIP (op/[TAG] One Piece - 00 [quality].mkv): Invalid serial# '0' for One Piece
renamed 'op/[TAG] One Piece - 52 [quality].mkv' -> 'op/[TAG] One Piece - S04E05 [quality].mkv'
...
renamed 'op/[TAG] One Piece - 865 [quality].mkv' -> 'op/[TAG] One Piece - S19E87 [quality].mkv'
SKIP (op/[TAG] One Piece - 875 [quality].mkv): Can't find serial# '875' for One Piece
renamed 'op/[TAG] One Piece - 295 [quality].mkv' -> 'op/[TAG] One Piece - S11E69 [quality].mkv'
...
renamed 'op/[TAG] One Piece - 430 [quality].mkv' -> 'op/[TAG] One Piece - S13E49 [quality].mkv'
SKIP (op/[TAG] One Piece - 876 [quality].mkv): Can't find serial# '876' for One Piece
renamed 'op/[TAG] One Piece - 655 [quality].mkv' -> 'op/[TAG] One Piece - S17E28 [quality].mkv'
...
renamed 'op/[TAG] One Piece - 93 [quality].mkv' -> 'op/[TAG] One Piece - S07E02 [quality].mkv'
renamed 'op/[TAG] One Piece - 278 [quality].mkv' -> 'op/[TAG] One Piece - S11E52 [quality].mkv'

# OK, but what happens when we run it again? Will our files be further renamed? Will Luffy find One Piece?
$ ./canon_vids op 
SKIP (op/[TAG] One Piece - 00 [quality].mkv): Invalid serial# '0' for One Piece
SKIP (op/[TAG] One Piece - 875 [quality].mkv): Can't find serial# '875' for One Piece
SKIP (op/[TAG] One Piece - 876 [quality].mkv): Can't find serial# '876' for One Piece

# Of course! Those files were never found in the lookup table, so they're still
# candidates for renaming. More importantly, no other files were touched.
  • Thx for everything :) – Vinanrra Feb 15 at 20:59
  • Soz to bother again, but what i need to edit so i can rename: [TAG] One Piece - 430 [quality][randomnumbers].mkv to: [TAG] One Piece - S13E49 [quality] PD: Im trying to edit myself the script but without results. @Adrian – Vinanrra Feb 18 at 17:08
  • I manage to do it reading some bash docs pages: if [[ $f =~ /([[^]]+])\ (.*)\ -\ ([0-9]+)\ ([[^]]+])([[^]]+].mkv) ]]; then # We've now split our filename into: ..... suffix="${BASH_REMATCH[5]}" – Vinanrra Feb 19 at 0:00

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.