Как узнать продолжительность всех видеофайлов в папке, содержащей несколько подпапок?

У меня есть папка с названием учебники. Внутри него около 15 папок, каждая из которых содержит около 15-20 .mp4 видео файлы. Я хочу получить общую продолжительность всех файлов, присутствующих в папке tutorials, Это код, который я написал до сих пор:

 for d in ~/Videos/tutorials/*; do
   if [ -d "$d" ]; then
     exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' ./*.mp4| tail -n1
   fi
 done

Приведенный выше код при выполнении выдает ошибку File not found: ./*.mp4 для каждой из подпапок, представленных внутри учебных пособий. Тем не менее, когда линия

exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' ./*.mp4| tail -n1

выполняется отдельно внутри каждой подпапки, я могу получить правильный вывод.

Какие изменения я должен внести в приведенный выше код, чтобы он заработал?

2 ответа

Решение

Вместо этого вы можете использовать это, чтобы найти все ваши mp4 в определенной папке и всех подпапках и суммировать их продолжительность в общую сумму. Это также заботится, если у них есть специальные символы, такие как пробел и т. Д.

find ~/Videos/tutorials/ -name "*.mp4" -printf "\"%p\" " | xargs exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n 1

Чтобы увидеть итоги каждой подпапки, а также

#!/bin/bash

SEARCHPATH=~/Videos/tutorials

echo "## TOTAL OF EVERY MP4"
find  $SEARCHPATH -name "*.mp4" -printf "\"%p\" " | xargs exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n 1

find $SEARCHPATH -type d  > /tmp/allFolders.txt

while read -r; do
echo "## TOTAL OF $REPLY"
find "$REPLY" -maxdepth 1 -name "*.mp4" -printf "\"%p\" " | xargs exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n 1
done < /tmp/allFolders.txt

#cleanup
rm /tmp/allFolders.txt

Вы должны заменить ./*.mp4 с "$d"/*.mp4:

 for d in ~/Videos/tutorials/*; do
   if [ -d "$d" ]; then
     exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' "$d"/*.mp4| tail -n1
   fi
 done

Ваш цикл for находит любые каталоги в ~/Videos/tutorials/ и присваивает его путь значению d переменная. Это каталог, который вы хотите проверить на наличие файлов mp4 с помощью exiftool, тогда как вы говорите exiftool использовать текущий каталог с ./,

Другой подход будет cd в каталог каждый раз, поэтому ваш код станет:

 for d in ~/Videos/tutorials/*; do
   if [ -d "$d" ]; then
     cd "$d"
     exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' ./*.mp4| tail -n1
   fi
 done

Следующий подход можно использовать, если у вас есть проблемные имена файлов для некоторых файлов mp4, например, содержащие пробелы. Сохраняет имена файлов в массив и расширяет их в кавычках exiftool команда.

 for d in ~/Videos/tutorials/*; do
       if [ -d "$d" ]; then
         cd "$d"
         files=(./*.mp4)         
         exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' "${files[@]}"| tail -n1
       fi
     done
Другие вопросы по тегам