匹配包含正則表達式標籤的字元串
我有一堆帶有相關字幕的影片文件。我正在嘗試編寫一個 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.mp4
andthing.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