ファイル名+目的の文字列に一致するファイルを含む変数を生成するためにループ内でfindを使用しようとしています。
例:
file1.en.srt
file1.mkv
file1.pt.srt
コードの関連部分は次のとおりです。
shopt -s nullglob
shopt -s nocaseglob
if [ -d "$1" ]; then
for file in "${1%/}/"*mkv; do
# Get filename to match against subs and audios
filename="$(basename "$file" .mkv)"
# Find matching subtitle file
engsubs="$(find . -name "$filename*en.srt*" | sed -e 's,^\./,,')"
# Find matching audio file
engaudio="$(find . -iname "$filename*en.ac3" -o -iname "$filename*en.eac3" -o -iname "$filename*en.dts" | sed -e 's,^\./,,')"
done
fi
ファイルに括弧がない場合は機能しますが、find
名前に括弧が含まれているファイルに対してはコマンドは何も見つかりません。なぜこれが起こるのですか?次の$en
ような変数を作成したいと思います。file1.en.srt
答え1
問題はグローバル[
文字]
です。たとえば、次のファイルを考えてみましょう。
ba[r].mkv
このファイルからスクリプトを実行すると、$filename
次のようになります。ba[r]
したがって、find
コマンドは次のようになります。
find . -name 'ba[r]*pt-BR.srt*'
[r]
これは単一文字の文字クラスなので、を意味します。したがって、コマンドは、で始まるファイル名、ランダムな文字、再びランダムな文字をr
探します。角かっこをエスケープする必要があります。ba
r
pt-BR.srt
find . -name 'ba\[r\]*pt-BR.srt*'
最も簡単な方法はとをprintf
使用することです%q
。したがって、次の行を変更してください。
filename="$(basename "$file" .mkv)"
これに関して:
filename=$(printf '%q' "$(basename "$file" .mkv)")
または、周辺コマンドを置き換えることなく次の操作を行いますprintf
。
printf -v filename '%q' "$(basename "$file" .mkv)"