2013-06-12 3 views
2

У меня есть коллекция переданных в эфир телевизионных эпизодов, все из которых названы в соответствии с форматом «Показать имя SXXEYY Episode Title.mp4», и я хотел бы добавить к ним теги iTunes mp4. У меня есть способ сделать это пометки из командной строки, но я хотел бы улучшить возможности сценариев оболочки и написать что-то, что может сделать это автоматически.Как я могу проанализировать имя файла в компонентах

Я понял, что сценарий bash сделает это для меня. В идеале правильно написанное регулярное выражение будет смотреть на имя файла и возвращать Show, Season, Episode и Title и разрешить мне передать эти результаты в мой инструмент тегов в скрипте bash. Правильно написанное регулярное выражение вернет BASH_REMATCH [1] .. [4] с этими четырьмя частями данных.

Вот где я застрял - я не могу заставить регулярные выражения работать.

Мое понимание синтаксиса подсказывает мне, что такие выражения, как:

Regex for Show Name: ^(?:(?! S[0-9][0-9]).)* 
Regex for Season Number: (?<=S)(.*)(?=E) 
Regex for Episode Number: (?<=S[0-9][0-9]E).. 
Regex for Episode Title: (?<=S[0-9][0-9]E[0-9][0-9])(.*)(?=.(mp4)) 

должны давать приемлемые результаты. Но до сих пор я не могу даже заставить bash возвращать любые аргументы. Я явно что-то отсутствует, но

#!/bin.bash 

for filename in "Cop Rock S01E03 Happy Mudder's Day.mp4" ; do 
    if [[ "$filename" =~ (?<=S[0-9][0-9]E[0-9][0-9])(.*)(?=.(mp4)) ]]; then 
     echo "${BASH_REMATCH[1]}${BASH_REMATCH[2]}" 
    fi 
done 

должен вернуть имя эпизод и суффикс mp4, но до сих пор результаты пока не ожидается.

Я также открыт для других решений, таких как sed, но я никогда не использовал sed раньше и едва ли могу его записать, поэтому кривая обучения, вероятно, будет крутой.

Я был бы очень признателен, если бы кто-нибудь мог указать на ошибку, которую я делаю. Это bash 3.2; Оператор = ~ работает.

ответ

5

Вы пытаетесь использовать регулярные выражения в стиле Perl (в частности, утверждение lookbehind с нулевой шириной), которое bash не понимает. Попробуйте следующее:

regex="(.*) S([0-9]{2})E([0-9]{2}) (.*)\.mp4" 
for filename in "Cop Rock S01E03 Happy Mudder's Day.mp4" ; do 
    if [[ "$filename" =~ $regex ]]; then 
     echo "Show: ${BASH_REMATCH[1]}" 
     echo "Season: ${BASH_REMATCH[2]}" 
     echo "Episode: ${BASH_REMATCH[3]}" 
     echo "Title: ${BASH_REMATCH[4]}" 
    fi 
done 
+0

'[0-9]' будет более кратким. – doubleDown

+0

Да. Не знаю, почему я изменил на '[[: digit:]]' когда я написал это регулярное выражение. Он вмещает другие локали, но это не проблема. – chepner

+1

Да, это решает. Благодаря! Дети моей деревни будут петь о вас. – user2479808

0

Я знаю, что это было 1,5 года с момента последней активности по этому вопросу, но я искал то же самое, и пришел в этот ответ. Я отлажены Ответ на этот вопрос немного более общий (разрешить для всех строчной файла, ползунков вместо пространств, различных расширений и нескольких имен файлов), поэтому я хотел бы поделиться обновление с вами:

#!/bin/bash 

regex="(.*)[ .][sS]([0-9]{2})[eE]([0-9]{2})[ .](.*)\.(mp4|mkv)" 
for filename in ${*} 
do 
    if [[ "${filename}" =~ ${regex} ]]; then 
     echo "Show: ${BASH_REMATCH[1]}" 
     echo "Season: ${BASH_REMATCH[2]}" 
     echo "Episode: ${BASH_REMATCH[3]}" 
     echo "Title: ${BASH_REMATCH[4]}" 
    fi 
done 

При копировании это в файл оболочки и сделать его исполняемым, вы можете использовать его более универсально.

Смежные вопросы