正規表現タグを含む文字列と一致します。

正規表現タグを含む文字列と一致します。

関連する字幕を含む動画ファイルがたくさんあります。字幕とビデオをmatroshkaコンテナにマージするbashスクリプトを作成しようとしています。

入力ビデオファイル名は、ソースコンテナに応じて「videoName.mkv」、「videoName.webm」、またはvideoName.mp4です。字幕ファイル名には「videoName.言語Code.vtt」と入力してください。出力ビデオファイル名は「subsvideoName」.mkv」です。

私が思いついたスクリプトは次のとおりです。

#!/bin/bash

for video in *; do
    if [[ $video =~ \.(mkv|webm|mp4)$ ]]; then
        [[ $video =~ \.(mkv|webm|mp4) ]]
        format=${BASH_REMATCH}
        [[ $video =~ .*[^$format] ]]
        name=${BASH_REMATCH}
        echo $name
        arsubs=()
        for subs in *; do
            echo "$subs"
            if [[ $subs =~ $name.*\.vtt$ ]]; then
                [[ $subs =~ \.[a-zA-Z0-9\-]*\.vtt$ ]]
                lang=$BASH_REMATCH
                [[ $lang =~ [^\.][a-zA-Z0-9\-]*[^\.] ]]
                lang=$BASH_REMATCH
                if [[ $lang =~ [a-z]*[^a-z]+ ]]; then
                    lang=$BASH_REMATCH
                    [[ $lang =~ [a-z]* ]]
                    lang=$BASH_REMATCH
                fi
                arsubs+=(--language 0:$lang)
                arsubs+=("$subs")
            fi
        done
        nameout=subs$name.mkv
        mkvmerge -o "$nameout" "$video" "${arsubs[@]}"
    fi
done

私が問題を抱えている正規表現は、[[ $subs =~ $nom.*.vtt$ ]] (行 13) です。ファイル名に正規表現タグ(「+」や「$」など)が含まれている場合、正規表現は一致しません。ファイル名にこれらの文字が含まれていない場合、スクリプトは正しく実行されます。

周りを見回したが、見つけることができる唯一の解決策は問題の文字をエスケープすることだけですが、ここではできないようです。

時間をいただきありがとうございます。

ベストアンサー1

正規表現の一致が多すぎて、非常にバイパス的な方法でこの問題にアプローチしているようです。

これはどうですか?

#!/bin/bash

shopt -s nullglob

for video in *.mkv *.webm *.mp4; do
        name=${video%.*}

        set -- "$name".*.vtt
        if [ -e "$1" ]; then
                lang=${1#$name.}
                lang=${lang%.vtt}

                mkvmerge -o "subs$name.mkv" "$video" --language "0:$lang" "$1"
        fi
done

.vttこれは、特定の項目に最初に見つかったファイルを使用すると仮定します$name(たとえば、複数の言語のファイルが複数ある場合.vtt)。

ループは、および3つのパターンのいずれかに一致する*.mkvすべての*.webm名前を繰り返します*.mp4。これにより、これらのサフィックスと一致することを確認するためにループ変数をテストする必要がなくなります。

にファイル名が与え$videoられたら、ファイル名サフィックス(何でも)を削除して名前部分を抽出します。これは私たちに$name

これによりsetパターンを一致させることができます"$name".*.vtt。このパターンが1つ以上のファイル名と一致する場合、そのファイル名はにあり、$1一致するファイル名の先頭と末尾を削除して言語部分(パターンのエントリと一致するビット)を抽出します。*$name..vtt

mkvmergeその後、必要な情報を提供するために電話をかけます。私たちいいえmkvmergeファイルがないと呼び出されます.vtt(あなたのコードがこれを行うようです)。

thing.mp4また、ファイル名のサフィックスの前に、などの同じ名前の複数のファイルがある場合、これらのファイルは同じ名前()を持つ同じコマンドをthing.mkv生成します。mkvmerge-osubsthing.mkv

.vttファイルを繰り返しながら、最も関心のあるファイル名に対応するビデオファイル形式を選択すると、この問題を解決できます.vtt

ただし、この目的のために正規表現を使用する必要はありません。

以下は、.vtt特定の名前を持つすべてのファイルを考慮するバリアントです。

#!/bin/bash

shopt -s nullglob

for video in *.mkv *.webm *.mp4; do
        name=${video%.*}

        sub_opts=()
        for sub in "$name".*.vtt; do
                lang=${sub#$name.}
                lang=${lang%.vtt}

                sub_opts+=( --language "0:$lang" "$sub" )
        done

        if [ "${#sub_opts[@]}" -gt 0 ]; then
                mkvmerge -o "subs$name.mkv" "$video" "${sub_opts[@]}"
        fi
done

おすすめ記事