找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 8442|回复: 9

[文本处理] [已解决]如何用BAT脚本批量处理ASS字幕:替换字体、删除日中对照及调整OP/ED对齐?

[复制链接]
发表于 2025-5-10 11:25:37 | 显示全部楼层 |阅读模式
本帖最后由 1139054012 于 2025-5-19 16:00 编辑

需求一:替换字幕样式字体
1. 根据分辨率匹配字体样式  
   根据 PlayResX 和 PlayResY 的值,选择对应的字体配置。
支持以下分辨率:
1920x1080
1280x720
720x480
640x360
480x272

这里举例1920x1080
Sub-CN => 方正准圆_GBK,63,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,2,10,10,20,1
Sub-CN-Top => 方正准圆_GBK,63,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,8,10,10,20,1

1280x720
....

每个分辨率样式名都有一套不同样式


修改前
  1. PlayResX: 1920 ← 主要判断这里
  2. PlayResY: 1080 ← 主要判断这里

  3. [Aegisub Project Garbage]
  4. Video AR Mode: 4
  5. Video AR Value: 1.777778
  6. Video Zoom Percent: 0.625000
  7. Scroll Position: 366
  8. Active Line: 393
  9. Video Position: 33883

  10. [V4+ Styles]
  11. Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
  12. Style: Sub-CN,方正正粗黑_GBK,60,&H00FFFFFF,&H000000FF,&H00404040,&H00000000,0,0,0,0,100,100,0,0,2,0,0,5,0,0,0,1  ← 主要通过分辨率通过样式名修改这里

  13. Style: Sub-CN-Top,方正正粗黑_GBK,60,&H00FFFFFF,&H000000FF,&H00404040,&H00000000,0,0,0,0,100,100,0,0,2,0,0,5,0,0,0,1   ← 主要通过分辨率通过样式名修改这里
复制代码
修改后
  1. PlayResX: 1920 ← 主要判断这里
  2. PlayResY: 1080 ← 主要判断这里

  3. [Aegisub Project Garbage]
  4. Video AR Mode: 4
  5. Video AR Value: 1.777778
  6. Video Zoom Percent: 0.625000
  7. Scroll Position: 366
  8. Active Line: 393
  9. Video Position: 33883

  10. [V4+ Styles]
  11. Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
  12. Style: Sub-CN,方正准圆_GBK,63,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,2,10,10,20,1  ← 主要通过分辨率通过样式名修改这里
  13. Style: Sub-CN-Top,方正准圆_GBK,63,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,8,10,10,20,1   ← 主要通过分辨率通过样式名修改这里
复制代码
2. 替换 Sub-CN/Default 样式  同上
   按照不同分辨率设置对应字体大小、颜色、描边等参数。


3. 替换随机字体名  
   将; Font subset:中定义的字体 ID(如 EJOPMNW2)替换为真实字体名称(如 方正兰亭细黑_GBK)。

修改前
  1. Style: Default,EJOPMNW2

  2. {\fnEJOPMNW2}
复制代码
修改后
  1. Style: Default,方正兰亭细黑_GBK

  2. {\fn方正兰亭细黑_GBK}
复制代码
4. 保留原始编码格式  
   支持 ANSI / UTF-8 带/无 BOM 编码,处理后不乱码。

需求二:删除日中对照内容
1. 过滤指定样式对话行  
   删除包含以下样式的 Dialogue 行:
Dial-JP
Dial-JP2
Dial_JP
Dial_JP2

修改前
  1. Dialogue: 0,0:01:13.44,0:01:16.41,Dial-CN,,0,0,0,,人
  2. Dialogue: 0,0:01:13.44,0:01:16.41,Dial-JP,,0,0,0,,人は别れるために逢い,死ぬために生れる。
  3. Dialogue: 0,0:01:13.44,0:01:16.41,Dial-CN,,0,0,0,,人
复制代码
修改后
  1. Dialogue: 0,0:01:13.44,0:01:16.41,Dial-CN,,0,0,0,,人
  2. Dialogue: 0,0:01:13.44,0:01:16.41,Dial-CN,,0,0,0,,人
复制代码
需求三:调整 OP/ED 字幕垂直位置

1. 识别 OP/ED 样式名  
   匹配样式名是否包含 OP 或 ED(不区分大小写)。

2. 修改垂直对齐方式  
若样式含 CN 或 CH,设为 2(底部)
若样式含 JP,设为 8(顶部)


修改前
  1. Style: OPCN,方正粗雅宋_GBK,60,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,4,0,1,2,0,2,20,20,20,1
  2. Style: OP_JP,FOT-Matisse Pro B,60,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0,8,20,20,20,1
复制代码
修改后
  1. Style: OPCN,方正粗雅宋_GBK,60,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,4,0,1,2,0,8,20,20,20,1
  2. Style: OP_JP,FOT-Matisse Pro B,60,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0,2,20,20,20,1
复制代码
test字幕
链接: https://pan.baidu.com/s/1p6F50WanmZqs3GGyCfHEUw?pwd=9mw5 提取码: 9mw5
发表于 2025-5-10 17:36:29 | 显示全部楼层
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit

  2. $s='Style: Sub-CN','Style: Default','Style: Staff'
  3. $font='方正准圆_GBK'
  4. $r=@{}
  5. @(
  6. (1920,1080,63),
  7. (1280,720,43),
  8. (720,480,28),
  9. (640,480,22),
  10. (480,272,16)
  11. )|%{
  12. $r[$_[0]]=@{$_[1]=@{font=$font}}
  13. foreach($i in $s){$r[$_[0]][$_[1]][$i]=$_[2]}
  14. }

  15. function is($file){
  16. $f=1
  17. $h=@{}
  18. $gf=gc -enc utf8 $file
  19. $gf|%{
  20. $i=$_
  21. if($f){
  22. if($_ -match 'Font subset end'){$f=0}
  23. if($_ -match '; Font subset:(.+)'){
  24. $a=$matches[1] -split '\s+'
  25. $h[$a[1]]=$a[3]
  26. }
  27. $i
  28. }else{
  29. if($i -match '^(PlayResX|PlayResY)\D*(\d+)'){set $matches[1] $matches[2]}
  30. $h.keys|%{
  31. $i=$i -replace $_,$h[$_]
  32. }
  33. if($i -match ($s -join '|')){
  34. $i=$i -split ','
  35. $i[1]=$r[[int]$PlayResX][[int]$PlayResY]['font']
  36. $i[2]=$r[[int]$PlayResX][[int]$PlayResY][$matches[0]]
  37. $i=$i -join ','
  38. }
  39. $i
  40. }
  41. }
  42. }

  43. is 1.ass|sc o.ass

  44. #dir *.ass|%{is $_|sc $_}
复制代码

评分

参与人数 1技术 +1 收起 理由
1139054012 + 1 感谢提供代码

查看全部评分

发表于 2025-5-11 14:22:08 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-5-11 14:24 编辑

回复 1# 1139054012

以下代码存为 test.bat 与源文件 *.ssa, *.ass 同目录运行,假设源文件均为 utf-8 编码,用源文件中的 playResX 数据匹配预设的字典列表,处理结果文件命名为 *.new.ssa 或 *.new.ass

  1. <# ::
  2. @echo off &powershell -c "iex(${%~f0}|out-string)" &pause&exit/b
  3. #>
  4. $r1, $r2, $r3 = 'Style: Sub-CN', 'Style: Default', 'Style: Staff'
  5. $d = @{
  6.   _a1920='方正准圆_GBK,63,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,2,10,10,20,1';
  7.   _b1920='方正准圆_GBK,43,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,8,10,10,20,1';
  8.   _a1280='方正准圆_GBK,43,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,15,1';
  9.   _b1280='方正准圆_GBK,43,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,15,1';
  10.   _a720='方正准圆_GBK,28,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,10,1';
  11.   _b720='方正准圆_GBK,28,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,10,1';
  12.   _a640='方正准圆_GBK,22,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,6,1';
  13.   _b640='方正准圆_GBK,22,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,6,1';
  14.   _a480='方正准圆_GBK,16,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,5,1';
  15.   _b480='方正准圆_GBK,16,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,5,1' }
  16. dir -file *.ssa,*.ass | % {
  17.   $s=(gc $_ -enc utf8); $x=$s -match 'playResX: (\d+)'; $x=($x[0] -split ': ')[1]
  18.   $s=$s -replace ($r1+',.*$'), ($r1+','+$d['_a'+$x])
  19.   $s=$s -replace ($r2+',.*$'), ($r2+','+$d['_a'+$x])
  20.   $s=$s -replace ($r3+',.*$'), ($r3+','+$d['_b'+$x])
  21.   $all=$s -match 'Font subset:.*$'
  22.   $m, $n=($s.length-1), ($all.length-1); $n=$s.Indexof($all[$n]); $sn=$s[($n+1)..$m]
  23.   foreach ($a in $all) { $a=$a.split(':-'); $sn=$sn -replace $a[1].trim(), $a[2].trim() }
  24.   [io.file]::writealllines($_.basename+'.new'+$_.extension, $s[0..$n]+$sn) }
  25. exit
复制代码

评分

参与人数 1技术 +1 收起 理由
1139054012 + 1 UTF-8可以替换,ANSI格式显示乱码

查看全部评分

发表于 2025-5-11 17:21:36 | 显示全部楼层
简单的ass还好
复杂的ass就难搞了
 楼主| 发表于 2025-5-17 16:39:33 | 显示全部楼层
本帖最后由 1139054012 于 2025-5-17 16:58 编辑

回复 4# Five66


2楼提出了一个思路,用ps1能实现,但是用3楼的bat就不行,ANSI,UTF-8有签名,无签名总有乱码和报错
 楼主| 发表于 2025-5-17 16:45:57 | 显示全部楼层
本帖最后由 1139054012 于 2025-5-17 16:47 编辑

回复 3# aloha20200628


    测试字幕ANSI格式会new会显示乱码
  1. ; Font subset: H2ZVBUDG - &#65533;&#65533;&#65533;&#65533;&#65533;д&#65533;&#65533;&#65533;&#65533;&#65533;_GBK
  2. ; Font subset: QOFKXI51 - FOT-TsukuBRdGothic Std
  3. ; Font subset: CZEVTX44 - TsukuBRdGothic Std Medium
  4. ; Font subset: 3HCI5I1G - &#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#1466;&#65533;_GBK
  5. ; Font subset: 04QYW4X8 - FOT-Matisse Pro
复制代码
带签名UTF-8的字幕文件



Get-Content : 找不到与参数名称“enc”匹配的参数。
所在位置 行:17 字符: 13
+   $s=(gc $_ -enc utf8); $x=$s -match 'playResX: (\d+)'; $x=($x[0] -sp ...
+             ~~~~
    + CategoryInfo          : InvalidArgument: ( [Get-Content],ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetContentCommand

无法将“IndexOf”的参数“value”(其值为“False”)转换为类型“System.Char”:“无法将值“False”转换为类型“System.Char”
。错误:“从“Boolean”到“Char”的强制转换无效。””
所在位置 行:22 字符: 42
+ ... m, $n=($s.length-1), ($all.length-1); $n=$s.Indexof($all[$n]); $sn=$s ...
+                                           ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

方法调用失败,因为 [System.Boolean] 不包含名为“split”的方法。
所在位置 行:23 字符: 26
+   foreach ($a in $all) { $a=$a.split(':-'); $sn=$sn -replace $a[1].tr ...
+                          ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [],RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

不能对 Null 值表达式调用方法。
所在位置 行:23 字符: 45
+ ... l) { $a=$a.split(':-'); $sn=$sn -replace $a[1].trim(), $a[2].trim() }
+                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [],RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Get-Content : 找不到与参数名称“enc”匹配的参数。
所在位置 行:17 字符: 13
+   $s=(gc $_ -enc utf8); $x=$s -match 'playResX: (\d+)'; $x=($x[0] -sp ...
+             ~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Content],ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetContentCommand

无法将“IndexOf”的参数“value”(其值为“False”)转换为类型“System.Char”:“无法将值“False”转换为类型“System.Char”
。错误:“从“Boolean”到“Char”的强制转换无效。””
所在位置 行:22 字符: 42
+ ... m, $n=($s.length-1), ($all.length-1); $n=$s.Indexof($all[$n]); $sn=$s ...
+                                           ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

方法调用失败,因为 [System.Boolean] 不包含名为“split”的方法。
所在位置 行:23 字符: 26
+   foreach ($a in $all) { $a=$a.split(':-'); $sn=$sn -replace $a[1].tr ...
+                          ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [],RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

不能对 Null 值表达式调用方法。
所在位置 行:23 字符: 45
+ ... l) { $a=$a.split(':-'); $sn=$sn -replace $a[1].trim(), $a[2].trim() }
+                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [],RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

请按任意键继续. . .
发表于 2025-5-17 17:19:46 | 显示全部楼层
回复 1# 1139054012

楼主是用 5-11 日1楼原帖的示例文件运行3楼代码的吗?(注》3楼代码出帖前已用当日1楼示例调试通过)今日楼主重新改编的1楼示例已经与前不同了...
 楼主| 发表于 2025-5-17 17:23:08 | 显示全部楼层
本帖最后由 1139054012 于 2025-5-17 17:26 编辑

回复 7# aloha20200628


    对,是用最初的字幕文件测试的,1楼打包发的替换字幕字体集.exe就是最初举例代码
当初发了部分文本代码,文本有特殊字幕导致的
发表于 2025-5-18 21:17:10 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-5-18 21:39 编辑

回复 6# 1139054012

基于3楼代码并根据1楼增加的要求作了调整,需求三之一忽略(因不明其意),需求三之二以文字说明为准(忽略代码栏示例),代码假设被处理的*.ass文件仅有3种编码(utf-8, utf-8+bom, ansi或gb2312)...
以下代码(存为 test.bat 与源文件 *.ass 同目录运行)已用附件中 '编码test.exe' 包含的3个示例文件测试通过(win8.1,powershell v4)...

  1. <# ::
  2. @echo off &powershell -c "iex(${%~f0}|out-string)" &pause&exit/b
  3. #>
  4. $r1, $r2, $r3 = 'Style: Sub-CN', 'Style: Default', 'Style: Staff'
  5. $d = @{
  6.   _a1920='方正准圆_GBK,63,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,2,10,10,20,1';
  7.   _b1920='方正准圆_GBK,43,&HFFFFFF,&H000000,&H000000,&H000000,1,0,0,0,100,100,1,0,1,1,1,8,10,10,20,1';
  8.   _a1280='方正准圆_GBK,43,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,15,1';
  9.   _b1280='方正准圆_GBK,43,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,15,1';
  10.   _a720='方正准圆_GBK,28,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,10,1';
  11.   _b720='方正准圆_GBK,28,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,10,1';
  12.   _a640='方正准圆_GBK,22,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,6,1';
  13.   _b640='方正准圆_GBK,22,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,6,1';
  14.   _a480='方正准圆_GBK,16,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,8,10,10,5,1';
  15.   _b480='方正准圆_GBK,16,&H00FFFFFF,&H00000000,&H00000000,&H00000000,-1,0,0,0,100,100,1,0,1,1,0,2,10,10,5,1'
  16. }
  17. $f=$pwd.path+'\f.gb'; dir -file *.ass | % {
  18.   $b=gc $_ -enc byte; if ($b[0] -eq 239 -and $b[1] -eq 187 -and $b[2] -eq 191) {$ec='UTF8'} else {
  19.   $s=gc $_ -raw -readcount 1000; [io.file]::writealltext($f, $s, [Text.Encoding]::default)
  20.   if ((gc $_ -enc byte).length -eq (gc $f -enc byte).length) {$ec='default'} else {$ec='utf8'} }
  21.   $s=gc $_ -enc $ec | where {$_ -notmatch 'JP[\d]*,,'}
  22.   $x=$s -match 'playResX: (\d+)'; $x=($x[0] -split ': ')[1]
  23.   $s=$s -replace ($r1+',.*$'), ($r1+','+$d['_a'+$x])
  24.   $s=$s -replace ($r2+',.*$'), ($r2+','+$d['_a'+$x])
  25.   $s=$s -replace ($r3+',.*$'), ($r3+','+$d['_b'+$x])
  26.   $all=$s -match 'Font subset:.*$'
  27.   $m, $n=($s.length-1), ($all.length-1); $n=$s.Indexof($all[$n]); $sn=$s[($n+1)..$m]
  28.   foreach ($a in $all) {$a=$a.split(':-'); $sn=$sn -replace $a[1].trim(), $a[2].trim()}
  29.   for ($i,$g,$l=0,0,$sn.length;$i -le $l;++$i) {$v=$sn[$i];if(($v -notmatch '^Style: ') -and $g -ne 0){break}elseif($v -match 'JP'){$g++;$v=$v.split(',');$v[18]=8;$sn[$i]=$v -join ','}elseif($v -match '(CN)|(CH)'){$g++;$v=$v.split(',');$v[18]=2;$sn[$i]=$v -join ','}}
  30.   if ($ec -ceq 'utf8') {[io.file]::writealllines($_.basename+'.new'+$_.extension, $s[0..$n]+$sn)} else {[io.file]::writealllines($_.basename+'.new'+$_.extension, $s[0..$n]+$sn, [text.Encoding]::$ec)}
  31. }
  32. del 'f.gb'; exit
复制代码

评分

参与人数 1技术 +1 收起 理由
1139054012 + 1 辛苦了

查看全部评分

 楼主| 发表于 2025-5-19 16:00:24 | 显示全部楼层
回复 9# aloha20200628


     辛苦了,发现需求有些多,bat不方便实现,通过ps1实现了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 06:00 , Processed in 0.025953 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表