検索:名前パターンにワイルドカード文字を使用する

検索:名前パターンにワイルドカード文字を使用する

ビデオを再生するための簡単なラッパースクリプトがあります。ここで私のスクリプトは、与えられたビデオファイルの字幕ファイル(存在する場合)を見つけようとします。ビデオ名が与えられたら、.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.vttfoo.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.mp42つの字幕ファイルfoo.de.vttfoo.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互換.)

おすすめ記事