Bash

匹配包含正則表達式標籤的字元串

  • November 25, 2020

我有一堆帶有相關字幕的影片文件。我正在嘗試編寫一個 bash 腳本,將字幕和影片合併到 matroshka 容器中。

輸入影片文件根據原始容器命名為“videoName.mkv”、“videoName.webm”或videoName.mp4。輸入字幕文件命名為“videoName.languageCode.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 行)如果文件名包含正則表達式標記,例如“+”或“$”,則不匹配。如果文件名不包含此類字元,則腳本執行良好。 我環顧四周,但我能找到的唯一解決方案需要轉義有問題的字元,我認為這在此處無法完成。

感謝您的時間。

您似乎以一種非常迂迴的方式進行此操作,正則表達式匹配太多。

那這個呢?

#!/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。這樣您就不必針對這些後綴測試您的循環變數來確定它是否與其中任何一個匹配。

給定 in 中的文件名$video,然後通過簡單地刪除文件名後綴來提取名稱部分,無論它是什麼。這給了我們$name.

然後,set我們匹配模式"$name".*.vtt。如果此模式與至少一個文件名匹配,則該文件名將是 in $1,我們通過從匹配文件名的前面和末尾*刪除來提取它的語言部分(與模式中匹配的位) 。$name.``.vtt

然後我們呼叫mkvmerge必要的資訊位。如果沒有文件(您的程式碼似乎正在這樣做),我們不會呼叫。mkvmerge``.vtt

還要注意,如果在文件名後綴之前有多個同名文件,例如thing.mp4and thing.mkv,那麼這些將導致mkvmerge具有相同名稱的相同命令-o( substhing.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

引用自:https://unix.stackexchange.com/questions/621412