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.

5
  • 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, 2019 at 14:12
  • For example: If its: 870, S08E70
    – Vinanrra
    Feb 15, 2019 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, 2019 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, 2019 at 17:04
  • I changed first post i think now i explained batter
    – Vinanrra
    Feb 15, 2019 at 17:27

1 Answer 1

1

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.
3
  • Thx for everything :)
    – Vinanrra
    Feb 15, 2019 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, 2019 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, 2019 at 0:00

You must log in to answer this question.

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