Automate renaming of video files

后端 未结 4 2104
再見小時候
再見小時候 2021-01-16 13:01

I have a lot of files I want to rename and it would take me a long time to do them manually. They are video files and are usually in this format - \"NAME OF SHOW - EPISODE N

相关标签:
4条回答
  • 2021-01-16 13:39

    The following solution:

    • works with both 3-digit and 4-digit season+episode specifiers (e.g. 107 for season 1, episode 7, or 1002 for season 10, episode 2)
    • demonstrates advanced find and bash techniques, such as:
      • the -regex primary to match filenames by regular expression (rather than wildcard pattern, as with -name)
      • execdir to execute a command in the same directory as each matching file (where {} contains the matching file name only)
      • invoking an ad-hoc bash script that demonstrates regular-expression matching with =~ and capture groups reported via the built-in ${BASH_REMATCH[@]} variable; command substitution ($(...)) to left-pad a value with zeros; variable expansion to extract substrings (${var:n[:m]}).
    # The regular expression for matching filenames (without paths) of interest:
    # Note that the regex is partitioned into 3 capture groups 
    # (parenthesized subexpressions) that span the entire filename: 
    #  - everything BEFORE the season+episode specifier
    #  - the season+episode specifier,
    #  - everything AFTER.
    # The ^ and $ anchors are NOT included, because they're supplied below.
    fnameRegex='(.+ - )([0-9]{3,4})( - .+)'
    
    # Find all files of interest in the current directory's subtree (`.`)
    # and rename them. Replace `.` with the directory of interest.
    # As is, the command will simply ECHO the `mv` (rename) commands.
    # To perform the actual renaming, remove the `echo`.
    find -E . \
     -type f -regex ".+/${fnameRegex}\$" \
     -execdir bash -c \
       '[[ "{}" =~ ^'"$fnameRegex"'$ ]]; se=$(printf "%04s" "${BASH_REMATCH[2]}");
       echo mv -v "{}" "${BASH_REMATCH[1]}S${se:0:2}E${se:2}${BASH_REMATCH[3]}"' \;
    
    0 讨论(0)
  • 2021-01-16 13:39

    Using the perl rename implementation which easily can take care of proper padding and works for any number of seaons and episodes (<100, but can easily be adapted to your current format):

    $ ls -1 *.avi
    My Show - 0301 - Qux.avi
    My Show - 101 - Foo.avi
    My Show - 102 - Bar.avi
    My Show - 1102 - Blah.avi
    My Show - 201 - Quux.avi
    
    $ rename -n 's/- (\d+)(\d{2,}) -/sprintf("- S%02dE%02d -", $1, $2)/e' *.avi
    My Show - 0301 - Qux.avi renamed as My Show - S03E01 - Qux.avi
    My Show - 101 - Foo.avi renamed as My Show - S01E01 - Foo.avi
    My Show - 102 - Bar.avi renamed as My Show - S01E02 - Bar.avi
    My Show - 1102 - Blah.avi renamed as My Show - S11E02 - Blah.avi
    My Show - 201 - Quux.avi renamed as My Show - S02E01 - Quux.avi
    

    I think homebrew ships with the correct version, so it's just a matter of installing via

    $ brew install rename
    
    0 讨论(0)
  • 2021-01-16 13:44
    for FOO in *; do mv "$FOO" "`echo $FOO | sed 's/\([^-]*\) - \([0-9]\)\([0-9][0-9]\)\(.*\)/\1 - S0\2E\3\4/g'`" ; done
    

    This works if there are less than 10 seasons.

    0 讨论(0)
  • 2021-01-16 14:00

    The following script will find all .mp4 with one string of 3 consecutive numbers. Example something.111.mp4 . It will convert it to something.S01E11.mp4 . It will also exclude any sample files.

    find . ! -name "*sample*" -name '*.[0-9][0-9][0-9].*.mp4' -type f | while read filename; do mv -v "${filename}" "`echo $filename | sed -e 's/[0-9]/S0&E/;s/SS00E/S0/g'`";done;
    

    Like the previous script it will only work if less than 10 seasons.

    For those that are trying to personalize for their current directory tree, I would recommend learning the sed and find command. They are pretty powerful, are simple, and will allow you to substitute any string within a file name.

    0 讨论(0)
提交回复
热议问题