Search code examples
regexbashoctal

Script failing in rename of files containing 08 or 09 in filename


I have been trying to use the below script to link all of the tv shows in my itunes eg:

  • ./iTunes/iTunes Media/TV Shows/Rookie Blue/Season 5/01 Blink.m4v
  • ./iTunes/iTunes Media/TV Shows/Haven/Season 3/11 Last Goodbyes.m4v
  • ./iTunes/iTunes Media/TV Shows/Doctor Who (2005)/Season 5/10 Vincent and the Doctor.m4v

to a new directory with the format of ./TVShows/Show.Name/Season.nn/Show.Name.SnnEnn.Episode.Name.m4v e.g:

  • ./TVShows/Rookie.Blue/Season.05/Rookie.Blue.S05E01.Blink.m4v
  • ./TVShows/Haven/Season.03/Haven.S03E11.Last.Goodbyes.m4v
  • ./TVShows/TV Shows/Doctor.Who.2005/Season.05/Doctor.Who.2005.S05E10.Vincent.and.the.Doctor.m4v
#! /bin/bash
srcroot="./iTunes/iTunes Media/TV Shows"
destroot="./TVShows"
for f in "$srcroot"/*/*/*.{m4v,mp4,avi}
do
    [[ -f $f ]] || continue
    IFS=/ read -a vid <<< "${f// /.}"
    vid=( "${vid[@]: -3}" )
    show=${vid[0]}
    season=${vid[1]}
    episode=${vid[2]}
    [[ $show =~ \([0-9]{4}\)$ ]] && show=${show: 0:${#show}-6}${show: ${#show}-5:4}
    sn=${season#*.}
    IFS=. read ep eptitle <<< "${episode%.*}"
    ext=${episode##*.} 
    printf -v hldir -- '%s/%s/%s' "$destroot" "$show" "$season"
    printf -v hlname -- '%s.s%02de%02d.%s.%s' "$show" "$sn" "$ep" "$eptitle" "$ext"
    echo "from: '$f'"
    echo "to: '$hldir/$hlname'"
    mkdir -p "$hldir"
    ln "$f" "$hldir/$hlname"
    echo
done

This script seems to mostly do what I want, except whenever it encounters episode numbers 08 or 09 e.g:

  • ./iTunes/iTunes Media/TV Shows/12 Monkeys/Season 01/08 Tomorrow.m4v
  • ./iTunes/iTunes Media/TV Shows/12 Monkeys/Season 01/09 Yesterday.m4v

gets linked to:

  • ./TVShows/12.Monkeys/Season.01/12.Monkeys.s01e00.Tomorrow.m4v
  • ./TVShows/12.Monkeys/Season.01/12.Monkeys.s01e00.Yesterday.m4v

Can anyone tell me why this is happening, and how I can fix it?


Solution

  • printf %02d 08 09
    

    fails with

    bash: printf: 08: invalid octal number
    bash: printf: 09: invalid octal number
    

    That's because numbers starting with 0 are interpreted as octal numbers, and octal numbers can only contain characters 0-7. Remove the leading zeros. In bash, you can use

    x=008
    printf %02d $((10#$x))
    

    which interprets the number as decimal.

    You can also use $(printf %s "$x" | sed 's/^00*//')