
해상도가 다른 여러 개의 비디오 파일이 있습니다. 이제 예를 들어 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: File read error" 메시지만 수신됩니다.
find -exec mediainfo "{}" \; -exec bash -c 'sm=$(mediainfo ${} | grep 720) : ; echo $sm' \;
내가 말했듯이 'if' 구성은 (실제 디렉토리에 대해) 작동하지만 find로도 실행되도록 노력할 것입니다.