정규식 태그가 포함된 문자열과 일치합니다.

정규식 태그가 포함된 문자열과 일치합니다.

관련 자막이 포함된 동영상 파일이 많이 있습니다. 자막과 비디오를 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).

루프는 , 및 세 가지 패턴 중 하나와 일치하는 *.mkv모든 *.webm이름을 반복합니다 *.mp4. 이렇게 하면 이러한 접미사와 일치하는지 확인하기 위해 루프 변수를 테스트할 필요가 없습니다.

에 파일 이름이 주어 $video지면 파일 이름 접미사(무엇이든)를 제거하여 이름 부분을 추출합니다. 이것은 우리에게 $name.

이를 통해 set패턴을 일치시킬 수 있습니다 "$name".*.vtt. 이 패턴이 하나 이상의 파일 이름과 일치하면 해당 파일 이름은 에 있을 것이며 $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

관련 정보