Удалить элементы текстового файла EDL, выполнить арифметические действия с другими частями

У меня есть просто отформатированный текстовый файл (Редактировать список решений) со строками чисел (частота кадров тайм-кода 25), за которыми следуют строки свойств (имена и т. д.).

В конечном итоге я пытаюсь:

  1. получить строки, начинающиеся с * FROM CLIP NAME:  , и строку/строку (тайм-код) непосредственно выше. В этой строке находятся временные коды, есть 4 группы чисел, каждая из которых выражается как 00:00:00:00 - или ЧЧ:ММ:СС:КФ или Часы, минуты, секунды, кадры. Потом отбрасываю все остальное.

  2. Используйте первые две группы чисел (это время начала и окончания), чтобы получить длительность.

  3. Затем добавьте duration к строке названия клипа.

  4. Сохраните файл как «SourceFileName».txt (исходный файл — .edl, чтобы он не перезаписывался).

Поскольку моя частота кадров составляет 25 кадров в секунду, я ожидал разложить каждую группу на количество кадров.

Я ожидал преобразовать таймкод в 25 кадров в секунду:

  • часов к базе времени кадра (25 кадров в секунду) 1 час = 1 * 60 * (60 * 25) = 9000
  • минут к базе времени кадра (25 кадров в секунду) 1 минута = 1 * (60 * 25) = 1500
  • секунд к базе времени кадра (25fps) 1 секунда = 1*25f

Получится группа из 00:02:20:01 = 3501 кадр.

  • 3501 целочисленное деление // 25 кадров в секунду = 140 секунд
  • 3501 по модулю (%) 25 = 1 остаток кадра

  • 140/60 = 2 мин.

  • 140%60 = 20 сек.

Затем я вычитал первую группу из второй, чтобы найти разницу. Как только у меня есть разница, я перекомпоновываю количество кадров в тайм-код, просто обращая математику.

Я не могу понять, как указать строку имени, а затем взять предыдущую строку для арифметики, используя первые 2 из 4 групп.

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

Option Explicit
Dim fso, oFile, y

Set fso = CreateObject("Scripting.FileSystemObject")

'get user to open file name
y = InputBox("name of file to save")

'next line opens a file with that name 
Set oFile = fso.OpenTextfile(y & ".edl")

ОБНОВЛЕНИЕ: исправлен сценарий, но я даже не могу сгруппировать выбранные строки и их начальные/конечные значения

Option Explicit
Dim fso, oFile, y, re, prev, line, matches

Set fso = createobject("Scripting.FileSystemObject")

'get user to open file name
y = inputbox("name of file to save")

'next line opens a file with that name 
Set oFile = fso.Opentextfile(y&".edl")

Do Until oFile.AtEndOfStream
    line = oFile.ReadLine
    'At this point the variable prev either is empty (during the first loop
    'cycle) or holds the content of the previous line.
    If Left(line, 21) = "*  FROM CLIP NAME:   " Then
        'do stuff here
        Set re = New RegExp
        re.Pattern = "C        (\d{2}:\d{2}:\d{2}:\d{2})    (\d{2}:\d{2}:\d{2}:\d{2})"
        matches = re.Execute(prev)
        'print each pair of prev & Pattern match
        prev = (line) & (matches)
        wscript.echo prev
        'don't know how to use submatch values
    End If

Loop

Пример файла .edl:

TITLE: test logan
* COMMENT:  CREATED BY GRASS VALLEY FOR EDIUS (CMX-3600) 
001  0000     A     C        00:00:04:23 00:00:42:04 00:00:00:00 00:00:37:06
* FROM CLIP NAME:  12 - Tech Sexy - D Cebert - FFP170
002  0000     A     C        00:00:20:01 00:00:31:23 00:01:29:24 00:01:41:21
* FROM CLIP NAME:  03 - Web Of Deceit (Main) - J Woodall - SFT164
003  0000     A     C        00:00:31:23 00:00:31:23 00:01:41:21 00:01:41:21
M2   0000        025.0              00:00:31:23
003  0000     A     D    025 00:00:31:09 00:00:54:12 00:01:41:21 00:02:04:24
* EFFECT NAME: CROSS DISSOLVE
* FROM CLIP NAME:  03 - Web Of Deceit (Main) - J Woodall - SFT164
* TO CLIP NAME:  03 - Web Of Deceit (Main) - J Woodall - SFT164
M2   0000        025.0              00:00:31:09
004  0000     A2    C        00:01:15:08 00:01:31:24 00:01:48:04 00:02:04:20
* FROM CLIP NAME:  12 - Environs A - T Juckes, S Kidd - SCDV354
005  0000     A2    C        00:00:11:12 00:00:30:05 00:02:06:24 00:02:25:17
* FROM CLIP NAME:  13 - Contagion (Main) - J Woodall - SFT164
006  0000     A2    C        00:00:06:13 00:00:56:09 00:02:27:04 00:03:17:00
* FROM CLIP NAME:  03 - Web Of Deceit (Main) - J Woodall - SFT164
007  0000     A2    C        00:00:56:09 00:00:56:09 00:03:17:00 00:03:17:00
M2   0000        025.0              00:00:56:09
007  0000     A2    D    025 00:00:55:08 00:01:54:03 00:03:17:00 00:04:15:20
* EFFECT NAME: CROSS DISSOLVE
* FROM CLIP NAME:  03 - Web Of Deceit (Main) - J Woodall - SFT164
* TO CLIP NAME:  03 - Web Of Deceit (Main) - J Woodall - SFT164
M2   0000        025.0              00:00:55:08
008  0000     A2    C        00:01:15:08 00:01:37:12 00:05:04:10 00:05:26:14
* FROM CLIP NAME:  12 - Environs A - T Juckes, S Kidd - SCDV354
009  0000     A2    C        00:00:00:00 00:00:26:19 00:06:00:08 00:06:27:02
* FROM CLIP NAME:  38 - Signs Of Pollution - W Plass - SCDV354
010  0000     A2    C        00:00:25:08 00:01:13:03 00:06:39:16 00:07:27:11
* FROM CLIP NAME:  38 - Signs Of Pollution - W Plass - SCDV354
011  0000     A2    C        00:01:13:03 00:01:13:03 00:07:27:11 00:07:27:11
M2   0000        025.0              00:01:13:03
011  0000     A2    D    025 00:01:48:22 00:02:04:09 00:07:27:11 00:07:42:23
* EFFECT NAME: CROSS DISSOLVE
* FROM CLIP NAME:  38 - Signs Of Pollution - W Plass - SCDV354
* TO CLIP NAME:  38 - Signs Of Pollution - W Plass - SCDV354
M2   0000        025.0              00:01:48:22

Я должен сделать это на VBScript, чтобы мы могли запускать его на рабочих столах Windows разных пользователей. Мы не можем установить другие исполняемые файлы или запустить их из командной строки. У меня нет прав для установки с правами администратора.


person 3pointedit    schedule 14.05.2018    source источник


Ответы (1)


Запомните предыдущую строку в отдельной переменной при чтении файла:

Do Until oFile.AtEndOfStream
    line = oFile.ReadLine
    'At this point the variable prev either is empty (during the first loop
    'cycle) or holds the content of the previous line.
    If Left(line, 19) = "* FROM CLIP NAME:  " Then
        'do stuff here
    End If
    prev = line
Loop

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

Set re = New RegExp
re.Pattern = "        (\d{2}:\d{2}:\d{2}:\d{2}) (\d{2}:\d{2}:\d{2}:\d{2})"
Set matches = re.Execute(prev)

Временные метки доступны как первое и второе совпадение matches.

Однако имейте в виду, что некоторым из FROM CLIP NAME строк в вашем входном файле не предшествуют строки с метками времени, поэтому вам придется с этим справиться.

person Ansgar Wiechers    schedule 14.05.2018
comment
Ого, спасибо, мне было интересно, как удерживать линию, пока вторая строка не станет правильной. Я буду копаться в этом выражении, хотя я не понимаю, как они хранятся в re.Pattern? - person 3pointedit; 14.05.2018
comment
@3pointedit Это не так. re.Pattern определяет шаблон, с которым вы хотите сопоставить линии. Затем re.Execute сопоставляет этот шаблон с заданной строкой (в данном случае со строкой в ​​переменной prev). - person Ansgar Wiechers; 14.05.2018
comment
Могу ли я использовать эти совпадающие временные метки в качестве списков, чтобы я мог выполнять арифметические действия для каждой части? Поскольку я не вижу, где их можно хранить в качестве переменной. Когда я запускаю это выражение в regex101, я вижу, что они находятся в группе1 и группе2. Как я могу получить доступ к этим группам? - person 3pointedit; 15.05.2018
comment
Временные метки извлекаются в виде строк. Прежде чем вы сможете использовать данные в арифметических операциях, потребуются дальнейшие преобразования. Для получения дополнительной помощи в этом, пожалуйста, напишите новый вопрос. Что касается доступа к группам захвата (частичным совпадениям в терминах VBScript), см. ссылку в моем ответе. Я положил его туда не просто так. Обратите особое внимание на раздел Извлечение подстрок. - person Ansgar Wiechers; 15.05.2018
comment
Ок, спасибо. Я очень ценю вашу помощь. Мне трудно увидеть разницу между именами переменных и функциями - person 3pointedit; 15.05.2018
comment
@3pointedit Пожалуйста, не перемещайте цель. Если у вас есть новый или дополнительный вопрос: опубликуйте новый вопрос. Если вы обнаружите, что ответ на ваш текущий вопрос решил проблему, описанную в этом вопросе: рассмотрите возможность принятия этого ответа. - person Ansgar Wiechers; 21.05.2018
comment
Чтобы было ясно, первая часть говорит - оставьте эту строку, если следующая часть говорит * FROM CLIP NAME: , это правильно? Итак, мне нужно, по крайней мере, сделать следующее исключение для строк, которые не соответствуют шаблону? Это правильный трек? - person 3pointedit; 23.05.2018
comment
Нет. Это говорит сделать что-то, только если текущая строка начинается со строки '...'. Вам нужно запомнить строку независимо от этого, чтобы вы могли заглянуть в прошлое в следующей итерации цикла. VBScript не может заглянуть в будущее, поэтому он не знает, что будет читать дальше. - person Ansgar Wiechers; 23.05.2018
comment
Ой. Поэтому мне нужно захватить строку временной метки как отдельный объект И ее следующую строку имени, но только если они следуют определенному шаблону. Итак, я должен сначала определить этот шаблон, но я могу зацикливаться только на строке, а не на паре строк? Должен ли я начать другую страницу вопросов и задать это? - person 3pointedit; 23.05.2018
comment
В первой итерации line содержит 1-ю строку, prev не определено. В конце итерации prev присваивается значение line (т.е. 1-я строка). В следующей итерации line содержит 2-ю строку, prev содержит первую строку. В конце итерации prev снова присваивается значение line (т.е. 2-я строка). На следующей итерации lineсодержит 3-ю строку, prev содержит 2-ю строку. И так далее. Это означает, что когда line начинается со строки CLIP NAME, prev уже содержит строку метки времени. Теперь стало яснее? - person Ansgar Wiechers; 23.05.2018
comment
Я так думаю... Я попытаюсь получить WScript.Echo этих двух переменных, чтобы увидеть изменения. RegExp должен войти в цикл If, верно? - person 3pointedit; 23.05.2018
comment
Хорошо, после всего этого недоразумения с моей стороны, я могу заставить предложение if работать, но оно приводит к ошибкам в строке match = re.Execute(prev) — неправильное количество аргументов или неверное назначение свойства. Он жалуется на переменную prev? - person 3pointedit; 24.05.2018
comment
Ах, это моя ошибка. Вам нужно ключевое слово Set, потому что вы назначаете объект. Исправлено. - person Ansgar Wiechers; 24.05.2018
comment
Если match не строковая переменная, то что это? Я не могу просто Echo его отобразить? Я предполагаю, что мне нужно посмотреть на подматчи в матче? Если бы я знал тип объекта, я бы разобрался :D - person 3pointedit; 24.05.2018
comment
Разве это не должны быть совпадения WScript.Echo.SubMatches? - person 3pointedit; 24.05.2018
comment
Если вы сомневаетесь, прочитайте документация. - person Ansgar Wiechers; 24.05.2018
comment
Последний ответ на этот вопрос, чтобы сказать спасибо. Я сделал RTFM ;-) и интегрировал ваше решение с другим. Буду публиковать любые новые вопросы отсюда. - person 3pointedit; 25.05.2018