-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubmatcher.bash
121 lines (96 loc) · 3.41 KB
/
submatcher.bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env bash
set -eo pipefail
[[ $DEBUG ]] && set -x
get_se() {
# Extract season and episode numbers
[[ ${1} =~ ${2} ]] && {
season=${BASH_REMATCH[1]}
episode=${BASH_REMATCH[2]}
} || {
return 1
}
}
match_media() {
# Attempt to match subtitle file to a media file
local season=$1
local episode=$2
local mediafile="${3}"
[[ ${mediafile} =~ ${season}[eEx]${episode} ]] && return 0 || return 1
}
newfname() {
# Generate file name for subtitle file
local subfile="${1}"
local medianame="${2%.*}"
local subext="${subfile##*.}"
local newfilename="${medianame}.${language}.${subext}"
echo "${newfilename}"
}
language=${SUBLANG:-en}
declare -a patterns
# Define patterns in pairs of 'length' and 'pattern'. Where
# 'length' is the number of chars to test at once and 'pattern'
# the actual pattern to test those 'length' chars against.
patterns+=( "5" "([0-9]{2}).([0-9]{2})" )
if [[ "$0" == "$BASH_SOURCE" ]]; then
shopt -s nullglob
declare -a media_exts ; media_exts=( "mp4" "mkv" "avi" )
declare -a srt_files ; srt_files=( *.srt )
declare -a vid_files ; for ext in "${media_exts[@]}"; do vid_files+=( *.${ext} ); done
declare -a matched_subs # Keep track of matched subs and their new filenames
declare -a existing_subs # For subtitles that already match a media file
declare -a media_to_skip # Media files that already have a matching sub file
# Find media files that already have properly named subtitles and
# store their names
for vidfile in "${vid_files[@]}"; do
potential_subfile="${vidfile%.*}.${language}.srt"
[[ -e "${potential_subfile}" ]] && \
existing_subs+=( "${potential_subfile}" ) && \
media_to_skip+=( "${vidfile}" )
done
for srtfile in "${srt_files[@]}"; do
poffset=0; offset=0; season=; episode=;
matched=${#matched_subs[@]}
# Skip subtitle if it's one of the existing ones
for existing_sub in "${existing_subs[@]}"; do
[[ "${existing_sub}" == "${srtfile}" ]] && continue 2
done
echo "Checking: ${srtfile}"
while [[ $poffset -lt ${#patterns[@]} ]]; do
# Try to extract season and episode numbers
# Note: get_se doesn't echo back but saves to $season and $episode
patlength=${patterns[$poffset]}
while [[ ${srtfile:$offset:$patlength} =~ .{$patlength} ]]; do
get_se "${srtfile:$offset:$patlength}" "${patterns[$((poffset + 1))]}" && break
offset=$((offset + 1))
done
[[ $season && $episode ]] && {
echo "... Resolved to Season ${season}, Episode ${episode}"
for vidfile in "${vid_files[@]}"; do
# Skip media file if it already had a properly
# named subtitle file
for skips in "${media_to_skip[@]}"; do
[[ "${skip}" == "${vidfile}" ]] && break 2
done
match_media $season $episode "${vidfile}" && \
echo "... Match: ${vidfile}" && \
matched_subs+=( "${srtfile}" ) && \
matched_subs+=( "$(newfname "${srtfile}" "${vidfile}")" ) && \
break 2
done
}
poffset=$((poffset + 2))
done
[[ ${#matched_subs[@]} -eq $matched ]] && echo "... No match"
done
# The rename part
offset=0; renames=0; skips=0;
while [[ $offset -lt ${#matched_subs[@]} ]]; do
newname="${matched_subs[$((offset + 1))]}"
[[ -e "${newname}" ]] && skips=$((skips + 1)) || {
mv "${matched_subs[$offset]}" "${newname}"
renames=$((renames + 1))
}
offset=$((offset + 2))
done
printf "Renames: %d Skips: %d\n" $renames $skips
fi