У меня есть несколько видео файлов с разными разрешениями. Теперь я хочу перечислить только имена файлов видео, например, с разрешением 720p. Я предпочитаю один вкладыш в командной строке bash, и при выполнении я могу получить полезную информацию о видео, включая разрешение:

avconv -i video.mp4

но эта комбинация:

find -exec sh -c 'if [[ "$(avconv -i {}") == *720* ]] ; then echo 720 found; fi;'

выдает ошибку: exec - отсутствует аргумент.

Честно говоря, я почти не борюсь со структурами команд bash, особенно с комбинированными командами. Итак, что не так в моей комбинированной командной строке?

Спасибо.

3 ответа3

1

Может быть, эта команда включает в себя то, что вы ищете:

for i in *.mp4; do if [[ $(avconv -i $i) =~ .*720.* ]]; then echo $i; fi; done
0

На данный момент я нашел полезное решение:

 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

Здесь я могу зациклить все м ?? видеофайлы и напечатайте его имя, включая условие "720". Без части if я мог бы показать мне все видео и их разрешения.

Я решил это с помощью других ответов здесь.

Когда я пытаюсь объединить find и exec и часть do вышеупомянутого решения, я получаю только сообщения «E: File read error» как результат из mediainfo для каждой темы:

 find -exec mediainfo "{}" \; -exec bash -c 'sm=$(mediainfo ${} | grep 720) : ; echo $sm' \;

Как я уже сказал, конструкция 'if' работает (для реального каталога), но я постараюсь также запустить ее с find.

0

Это может быть удивительно, но -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 чтобы узнать больше.


РЕДАКТИРОВАТЬ:

Эта команда (mis) использует 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 , я думаю, вам нужно перенаправить его, прежде чем вы сможете его проанализировать,
  • и может быть что-то еще.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .