需要帮助来创建批处理文件以计算行数并在每行中返回值

时间:2019-01-06 06:18:56

标签: batch-file

需要浏览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 :(得分:1)

执行批处理文件的Windows命令处理器cmd.exe专用于运行命令和应用程序。它不适用于在文本文件中进行修改。还有许多其他脚本语言具有可轻松修改文本文件的功能,例如VBScript,JScript,PowerShell,Python,Perl等。因此,为此任务使用Windows命令处理器是最糟糕的决定,这可能由某人做出

但是,使用 Dave Benham 编写的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的文件,如果此条件不成立,则立即退出,请参阅Where does GOTO :EOF return to?

批处理文件 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 /?

答案 1 :(得分:1)

可以使用适当的方法以相对简单的方式在批处理文件(或任何其他编程语言)中解决此问题:

编辑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

读取行并将其存储在数组中,直到出现空行。在那一刻,所有行都被输出,并且附加数据被添加到第一行。当部分中的行数为3(包括最后一个空行)时,有些奇怪的算术表达式仅从90中减去6。有关更多详细信息,请参见SET /?