Shell

查找:在 -name 模式中使用萬用字元

  • October 12, 2022

我有一個簡單的包裝腳本來播放影片,我的腳本試圖找到給定影片文件的字幕文件(如果存在)。給定影片名稱,我正在尋找相同的名稱,僅以.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存在零個或一個匹配文件時才有效。如果兩個存在,則find返回以下錯誤:

/bin/find: paths must precede expression: `2207-_-20220620.en.vtt'
/bin/find: possible unquoted pattern after predicate `-name'?
subtitles not found

問題似乎是 find 為-name謂詞獲取了兩個參數。但是我不能引用該模式${video_file%.*}.*.vtt,因為這樣萬用字元*就會被逐字解釋。

我嘗試使用-regex具有相同結果的謂詞

我怎樣才能在我的腳本中實現我想要的?

你寫了,

但我不能引用該模式${video_file%.*}.*.vtt,因為這樣萬用字元*就會被逐字解釋

我認為在這種情況下,這正是您需要做的。引用該欄位會阻止 shell 將其作為 glob 應用,但它允許find查看文件名模式中的萬用字元。(find -name了解萬用字元模式本身 - 請參閱man find並蒐索解釋以-name獲取詳細資訊。)

如您的問題所述,我們假設影片文件是foo.mp4並且有兩個字幕文件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 標準。)

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