ビデオを再生するための簡単なラッパースクリプトがあります。ここで私のスクリプトは、与えられたビデオファイルの字幕ファイル(存在する場合)を見つけようとします。ビデオ名が与えられたら、.vtt
ビデオフォーマット拡張子の代わりに拡張子で終わる同じ名前を探しています。
#!/bin/sh
video_file="$1"
sub_file="$(/bin/find -name ${video_file%.*}.*.vtt)"
if [ -f "$sub_file" ] ; then
echo "subtitles found: $sub_file"
else
echo "subtitles not found"
fi
複数のサブファイルがある場合(たとえば、、最初foo.en.vtt
にfoo.de.vtt
見つかったサブファイルを使用したい)
問題は、上記のスクリプトが.vtt
一致するファイルが0個または1個ある場合にのみ機能することです。 2つがある場合は、find
次のエラーが返されます。
/bin/find: paths must precede expression: `2207-_-20220620.en.vtt'
/bin/find: possible unquoted pattern after predicate `-name'?
subtitles not found
-name
問題は、findが述部の2つのパラメータを取得することです。しかし、パターンを引用することはできません。${video_file%.*}.*.vtt
なぜなら、ワイルドカードが*
文字通り解釈されるからです。
述語を試してみましたが、-regex
同じ結果が得られました。
スクリプトで目的の効果をどのように取得できますか?
答え1
あなたは書いた、
しかし、パターンを引用することはできません。
${video_file%.*}.*.vtt
なぜなら、ワイルドカードが*
文字通り解釈されるからです。
私の考えでは、これがまさにこの場合にすべきことだと思います。このフィールドを引用すると、シェルがそれをglobとして適用するのを防ぎますが、find
ファイル名パターンにワイルドカード文字を表示できます。 (find -name
ワイルドカードパターン自体を理解してください。詳細についてman find
は説明を確認して検索してください-name
。)
あなたの質問で説明されているように、ビデオファイルはfoo.mp4
2つの字幕ファイルfoo.de.vtt
とfoo.en.vtt
。
このコードスニペットを使用して両方を識別できます。
video=foo.mp4
find . -name "${video_file%.*}.*.vtt" -print
この出力
./foo.de.vtt
./foo.en.vtt
最初の拡張だけを望んでいたので、POSIXではなく拡張を使用すると、-quit
最初の拡張のみを取得できます。
subtitles=$(find -name "${video_file%.*}.*.vtt" -print -quit)
echo "> $subtitles"
> ./foo.de.vtt
find
検索はディレクトリ順に行われるため、結果は必ずしもソートされた順序で返されるわけではありません。一致するファイル名に改行文字が含まれていないことを保証できる場合は、find … -print | sort | head -n1
現在のロケールに基づいてソートできます。 (それでもPOSIX互換.)