Как быстро определить время начала / окончания файлов, которые показывают только время начала? - PullRequest
0 голосов
/ 19 октября 2010

У меня есть огромный список видеофайлов с веб-камеры, которые выглядят так:

video_123
video_456
video_789
...

Где каждое число (123, 456 и 789) представляет время начала файла в секундах.с эпохи.Файлы создаются на основе размера файла и не всегда имеют одинаковую продолжительность.В файлах также могут быть пробелы (например, камера выключается на час).Это пользовательский формат файла, который я не могу изменить.

У меня есть инструмент, который может извлекать части видео с заданным диапазоном времени и набором файлов.Тем не менее, он будет работать НАМНОГО быстрее, если я дам инструменту только файлы с кадрами в заданном диапазоне.Это очень дорого, чтобы определить продолжительность каждого файла.Вместо этого я хотел бы использовать начальную временную метку, чтобы исключить большинство файлов.Например, если я хотел видео для 500-600, я знаю, что video_123 не понадобится, потому что video_456 больше.Кроме того, video_789 больше 600, поэтому в этом также не будет необходимости.

Я мог бы сделать ls и перебрать каждый файл, преобразовав временную метку в int и сравнивая, пока мы не достигнем файла большечем желаемый диапазон.У меня много файлов, и это медленно.Есть ли более быстрый метод?Я думал о том, чтобы иметь какое-то двоичное дерево, которое могло бы получить время поиска в log2n и уже разобрало временные метки.Я делаю большую часть этой работы в bash и предпочел бы использовать простые, распространенные инструменты, такие как grep, awk и т. Д. Однако я буду рассматривать Perl или какой-либо другой большой язык сценариев, если есть веская причина.

Ответы [ 2 ]

1 голос
/ 19 октября 2010

Если вы выполняете несколько операций поиска с файлами, вы можете предварительно обработать файлы, в смысле загрузки их в массив bash (note, bash, not sh), упорядочить их, а затем выполнить двоичный поиск. Предположим на секунду, что имя файла является просто меткой времени, это облегчит примеры (вы всегда можете сделать ${variable/video_/}, чтобы удалить префикс.)

Во-первых, вы можете использовать массив для загрузки всех отсортированных файлов:

files=(`echo * | sort -n`)

Затем реализуйте бинарный поиск (просто набросок, ищущий поз $min - $max):

nfiles=${#files[*]}
nfiles2=`expr $nfiles / 2`
if test ${files[$nfiles2]} -gt $max
then
    nfiles2=`expr $nfiles2 - $nfiles2/2`
else
    #check $min, etc.
fi

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

0 голосов
/ 21 октября 2010

Из-за причуд в дизайне UNIX нет способа искать имя файла в каталоге, кроме пошагового просмотра имен файлов по одному.Поэтому, если вы храните все свои файлы в одном каталоге, вы не получите намного быстрее, чем использовать ls.

Тем не менее, если вы хотите переместить ваши файлы, вы можете повернутьплоский каталог в дерево путем разбиения на наиболее значимые цифры.Вместо:

video_12301234
video_12356789
video_12401234
video_13579123

Вы могли бы иметь:

12/video_12301234
12/video_12356789
12/video_12401234
13/video_13579123

или даже:

12/30/video_12301234
12/35/video_12356789
12/40/video_12401234
13/57/video_13579123

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...