
我有幾個不同解析度的影片檔。現在我只想列出分辨率為 720p 等的視訊檔案名稱。我更喜歡 bash 命令列上的一個襯墊,當我執行以下命令時,我可以收到有用的視訊訊息,包括解析度:
avconv -i video.mp4
但這個組合:
find -exec sh -c 'if [[ "$(avconv -i {}") == *720* ]] ; then echo 720 found; fi;'
產生錯誤:exec - 缺少參數。
老實說,我幾乎沒有與 bash 命令結構發生衝突,尤其是組合命令。那麼,我的組合命令字串出了什麼問題呢?
謝謝。
答案1
也許這個指令可以滿足您的需求:
for i in *.mp4; do if [[ $(avconv -i $i) =~ .*720.* ]]; then echo $i; fi; done
答案2
這可能令人驚訝,但-exec
可以用作呼叫測試find
:
find -type f -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print
上述指令將下降到子目錄。要在當前目錄中搜索,只需使用-maxdepth 1
,即:
find -maxdepth 1 -type f -exec …
請注意,ffprobe
將測試所有文件。對於非媒體文件,它顯然會失敗,但您可能會.jpg
在最終輸出中獲得非視訊媒體(如)。為了避免這種情況,find
應該在之前使用一些額外的測試-exec
,例如:
find -maxdepth 1 -type f \( -iname "*.avi" -o -iname "*.mp4" -o -iname "*.mkv" \) -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print
或者更好的是,您可以使用以下命令測試 mime 類型file
:
find -maxdepth 1 -exec sh -c 'file --mime-type "$1" | grep -q "video/"' sh {} \; -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print
閱讀man find
以了解更多。
編輯:
avconv
根據您的要求,該命令(錯誤)使用了:
find -exec sh -c 'file --mime-type "$1" | grep -q "video/"' sh {} \; -exec sh -c 'avconv 2>&1 -i "$1" | grep -q "Stream.*x720"' sh {} \; -print
問題是avconv
其中的每次呼叫都會引發錯誤。我們只是忽略它並提取我們需要的資訊。這是一個有點醜陋的解決方案。我不完全確定你的avconv
行為和我的一樣,你可能需要用Stream.*x720
其他正規表示式替換。
我的組合命令字串有什麼問題?
find -exec
需要以\;
或結束+
,在您編輯問題後,沒有$(
)
與交錯""
(不是巢狀)$()
,*720*
可能會觸發外殼通配,應該是"*720*"
(我說的是sh
,而不是外殼),avconv
你嘗試解析的輸出會轉到stderr
,我認為你需要先重定向它,然後才能解析它,- 也許還有別的東西。
答案3
我不知道avconv,我通常使用ffmpeg。如果你安裝了它,你可以使用這個腳本
#!/bin/bash
OIFS="$IFS"
IFS=$'\n'
files=$(find ./ -type f -exec ls {} + | grep ".*\.mpg$\|.*\.avi$\|.*\.mkv$\|.*\.mp4$"| cut -c3-)
for f in ${files}
do
resolution=$(ffprobe -v error -select_streams v:0 -show_entries
stream=height -of csv=s=x:p=0 ${f})
printf "%-100s %-10s\n" $f $resolution
done
答案4
目前我找到了一個可用的解決方案:
for i in ls *.m??; do sm=$(mediainfo $i | grep Height | sed 's/ //g');if [[ "$sm" == *720* ]]; then printf "Video: %-s $i %-s $sm \n"; fi; done
在這裡我可以循環所有m?視訊檔案並列印其名稱,包括“720”條件。如果沒有 if 部分,我可以向我展示所有影片及其解析度。
我在其他答案的幫助下解決了這個問題。
當我嘗試將 find 和 exec 以及上述解決方案的 do 部分結合起來時,我只收到來自每個主題的 mediainfo 的「E:檔案讀取錯誤」訊息:
find -exec mediainfo "{}" \; -exec bash -c 'sm=$(mediainfo ${} | grep 720) : ; echo $sm' \;
正如我所說,“if”構造有效(對於實際目錄),但我也會嘗試使其與 find 一起運行。