Нужна помощь в создании командного файла для подсчета строк и возврата значений в каждой строке - PullRequest
0 голосов
/ 06 января 2019

Нужно пройти через WEBVTT (текстовый файл с простой информацией о вертикальном размещении для субтитров) и считать # строк и возвращаемое значение рядом с отметкой времени

Я новичок в этом и попробовал найти и заменить регулярные выражения, но это не сработало

У меня есть этот контент в файле с субтитрами:

WEBVTT

00:00:00.000 --> 00:00:02.160
Hello World
I am James

00:00:02.185 --> 00:00:04.990
Welcome to my Show!

00:00:12.038 --> 00:00:14.530
This is our new season.
We hope you enjoy the show

00:00:19.580 --> 00:00:21.840
This is the first episode.

И хотел бы, чтобы скрипт проверял каждый раздел с отметкой времени и возвращал это:

WEBVTT

00:00:00.000 --> 00:00:02.160 align:middle line:84%
Hello World
I am James

00:00:02.185 --> 00:00:04.990 align:middle line:90%
Welcome to my Show!

00:00:12.038 --> 00:00:14.530 align:middle line:84%
This is our new season.
We hope you enjoy the show!

00:00:19.580 --> 00:00:21.840 align:middle line:90%
This is the first episode.

Если есть одна строка, ТО возвращаемое значение рядом с отметкой времени будет
align:middle line:90% Остальное align:middle line:84%

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Эта проблема может быть решена относительно простым способом в пакетном файле (или любом другом языке программирования), используя правильный метод:

РЕДАКТИРОВАТЬ 2019-01-07: Исправлена ​​проблема с восклицательными знаками

@echo off
setlocal DisableDelayedExpansion

(

echo WEBVTT
echo/
set "i=0"
for /F "skip=2 tokens=1* delims=:" %%a in ('findstr /N "^" input.txt') do (
   set /A i+=1
   call set "line[%%i%%]=%%b"
   if "%%b" equ "" (
      set /A "line=90-!!(i-3)*6"
      setlocal EnableDelayedExpansion
      echo !line[1]! align:middle line:!line!%%
      for /L %%i in (2,1,!i!) do echo(!line[%%i]!
      endlocal
      set "i=0"
   )
)
set /A "line=90-!!(i-2)*6"
setlocal EnableDelayedExpansion
echo !line[1]! align:middle line:!line!%%
for /L %%i in (2,1,!i!) do echo(!line[%%i]!

) > output.txt

Строки считываются и сохраняются в массиве до появления пустой строки. В этот момент выводятся все строки и дополнительные данные добавляются в первую строку. Несколько странное арифметическое выражение просто вычитает 6 из 90, когда количество строк в разделе равно 3 (включая последнюю пустую строку). Подробнее см. SET /?.

0 голосов
/ 06 января 2019

Процессор команд Windows cmd.exe Выполнение командных файлов предназначено для запуска команд и приложений. Он не предназначен для внесения изменений в текстовые файлы. Есть много других языков сценариев, которые имеют функции для легкого изменения текстовых файлов, таких как VBScript, JScript, PowerShell, Python, Perl, ... Таким образом, использование командного процессора Windows для этой задачи является худшим решением, которое может принять кто-то .

Тем не менее, это, тем не менее, легко достижимая задача с использованием JREPL.BAT , написанного Дейвом Бенхамом , который представляет собой гибрид пакетного файла / JScript для выполнения замены регулярного выражения на файл с использованием JScript.

@echo off
if not exist "%~dp0jrepl.bat" goto :EOF
if not exist "WEBVTT" goto :EOF

call "%~dp0jrepl.bat" "(\d{2}:\d{2}:\d{2}\.\d{3} --\> \d{2}:\d{2}:\d{2}\.\d{3})(\r?\n[^\r\n]+\r?\n[^\r\n])" "$1 align:middle line:84%%$2" /M /F "WEBVTT" /O -
call "%~dp0jrepl.bat" "(\d{2}:\d{2}:\d{2}\.\d{3} --\> \d{2}:\d{2}:\d{2}\.\d{3})(\r?\n[^\r\n])" "$1 align:middle line:90%%$2" /M /F "WEBVTT" /O -

Пакетный файл сначала проверяет, существует ли файл с именем WEBVTT в текущем каталоге, и сразу же завершает работу, если это условие не выполняется, см. Куда возвращается GOTO: EOF?

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

Затем JREPL.BAT используется дважды для запуска двух замен регулярного выражения в файле WEBVTT, чтобы изменить его содержимое на требуемый формат.

Давайте посмотрим на первое поисковое выражение:

(\d{2}:\d{2}:\d{2}\.\d{3} --\> \d{2}:\d{2}:\d{2}\.\d{3})(\r?\n[^\r\n]+\r?\n[^\r\n])

( ... ) ... определяет группу маркировки. Строка, найденная выражением внутри этой первой группы разметки, имеет обратную ссылку $1 в строке замены, чтобы сохранить эту часть найденной и сопоставленной строки без изменений. Регулярное выражение внутри маркирующей группы используется для того, чтобы определенно найти строку со строкой, например 00:00:02.185 --> 00:00:04.990, где-либо внутри строки.

\d{2} ... означает, что для положительного совпадения необходимо найти ровно две цифры.

\. ... точка означает любой символ и поэтому должна быть экранирована обратной косой чертой, чтобы интерпретироваться как буквальный символ.

\d{3} ... означает, что для положительного совпадения необходимо найти ровно три цифры.

\> ... также > необходимо экранировать с помощью обратной косой черты, чтобы интерпретировать его как буквальный символ.

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

\r?\n ... должен быть перевод строки с произвольным возвратом каретки до, например, после 00:00:02.185 --> 00:00:04.990.

[^\r\n]+ ... следующая строка должна содержать один или несколько символов, не являющихся переводом каретки или переводом строки. Таким образом, поисковое выражение отрицательно на следующей строке, являющейся пустой строкой. Обратите внимание, что строка, содержащая только пробелы / табуляции, не является пустой строкой. Это пустая строка из-за того, что она содержит только пробелы, но это не пустая строка.

\r?\n[^\r\n] ... и, наконец, должна заканчиваться еще одна строка в DOS / Windows или UNIX, а в следующей строке также должен быть символ для положительного совпадения.

Таким образом, первое поисковое выражение сопоставляет строки с субтитрами в две строки.

Следовательно, первая строка замены содержит 84%, в результате чего знак процента должен быть экранирован еще одним знаком процента, потому что в противном случае командный процессор Windows будет интерпретировать % как начало переменной окружения или ссылки на аргумент пакетного файла.

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

Оба регулярных выражения являются многострочными, для которых требуется JREPL опция /M.

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

  • call /? ... также объясняет %~dp0 ... диск и путь аргумента 0, являющийся самим пакетным файлом.
  • echo /?
  • goto /?
  • if /?
  • jrepl.bat /?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...