按样式平移 ASS 字幕时间轴,并可选按时间 / 样式重组字幕的命令行小工具
中文 · English
ASSShift 把 ASS 字幕中指定样式(或不指定样式 = 全部行)的 Dialogue 行 Start / End 时间整体向前或向后平移 N 秒,并可同时完成两件整理工作:
-sort:按时间轴重排事件行(Subresync 逻辑),或先按样式分块、块内再按时间排序-mininfo:把[Script Info]精简为最小标准形式
典型用途:
- 双语字幕里各语言独立微调(如
JP/CN各调各的),或整个字幕整体延迟 / 提前 - 片头 / 片尾单独校正
- 跳过带
\pos等特效标签的排版行不动 - 把字幕组藏在零时长行(
Start = End)里的注释聚到最前,统一删除 - 免去 Subresync 的 UTF-16 LE 转码步骤,直接完成「排序 + 精简」重组
原始文件永不覆盖,处理结果写入同目录下的 fixed_<原名>.ass。
- ✨ 样式可选 —— 指定一个或多个样式(空格或逗号分隔)只平移它们;省略样式 = 整个字幕平移
- 🧹 两种排序模式 ——
-sort time纯时间轴重排(Subresync 逻辑);-sort style先按样式分块(块序 = 首次出现顺序),块内按时间排序;两种模式中零时长注释行都排最前,方便一把删除 - 🧼
-mininfo精简头部 ——[Script Info]重写为 6 键最小标准形式,丢弃注释与字幕组元数据 - 🎯
-Skip关键字排除 —— 正文含关键字的行保持不变(如\pos特效行),不区分大小写,可重复指定 - 📁 单文件 / 目录批量 —— 给文件名只处理该文件(支持通配符);不给则处理当前目录所有
*.ass - 🔒 原文件零修改 —— 输出
fixed_*.ass,且目录扫描自动跳过已有fixed_* - 🧷 编码与 BOM 完整保留 —— UTF-8 / UTF-8 BOM / UTF-16 LE/BE / ANSI 均按原样回写,无需像 Subresync 那样先转 UTF-16 LE
- ⏱ 时间钳制 —— 提前到
0:00:00.00之前的部分自动钳到0:00:00.00 - 🧠 命令行友好 —— 负数偏移、引号、逗号分隔的样式列表、
offset 0纯重组模式全部正确解析 - 📖 自文档化 ——
ASSShift -h即可查看完整用法
- Windows 7 / 10 / 11(任意带 Windows PowerShell 5.1 的版本)
- 无需额外依赖,PowerShell 与 .NET 均为系统自带
仓库只含两个文件,放到同一目录即可:
ASSShift.cmd ← 命令行入口(推荐通过它调用)
ASSShift.ps1 ← 实际处理脚本
建议把这个目录加入 PATH,之后可在任意位置直接调用 ASSShift。
保存提示:
ASSShift.cmd请以 ANSI 或 UTF-8(无 BOM)+ CRLF 保存(BOM 会让@echo off报错)。ASSShift.ps1内容为纯 ASCII,任何编码均可。
:: 整个字幕提前 0.2 秒(当前目录所有 *.ass)
ASSShift -0.2
:: 只平移 CN、JP 两种样式
ASSShift CN JP -0.2 abc.ass
:: 等价写法
ASSShift CN,JP -0.2 abc.ass
:: 平移 + 跳过 \pos 特效行
ASSShift CN JP -0.16 -Skip "\pos" abc.ass
:: 纯重组:不平移时间,按样式分块排序 + 精简 Script Info
ASSShift 0 -sort style -mininfo abc.assASSShift [styles...] <offset> [-Skip <keyword>] [-sort [time|style]] [-mininfo] [<files>...]
ASSShift [styles...] -offset <seconds> [-Skip <keyword>] [-sort [time|style]] [-mininfo] [<files>...]
ASSShift -h
一句话规则:offset 是分界线 —— 它之前的是样式名,它之后的是文件名。另外,以 .ass 结尾的 token 无论出现在哪里都视为文件(样式名不可能叫 xxx.ass),所以 ASSShift abc.ass -0.2 也合法。
| 参数 | 是否必需 | 说明 |
|---|---|---|
<styles...>(位置式) |
可选 | 一个或多个样式名,空格或逗号分隔均可:CN JP 等价于 CN,JP;省略样式 = 对所有样式的 Dialogue 行平移 |
<offset>(位置式) |
与 -offset 二选一 |
秒数。正数 = 延迟,负数 = 提前;offset 前第一个纯数字 token 即被识别为偏移;0 = 不平移(纯重组模式,需搭配 -sort / -mininfo) |
-style <list> / -styles <list> |
可选 | 显式指定样式列表;可在任意位置出现;可重复;用于纯数字样式名等边界情况 |
-offset <seconds> |
可选 | 显式指定偏移;比位置式更自文档化,推荐用于脚本 / 留档 |
-Skip <keyword> |
可选 | 正文 Text 含关键字的行保持不变;不区分大小写;可重复 -Skip a -Skip b,命中任一即跳过 |
-sort [time|style] |
可选 | 重排 [Events] 段事件行(默认不排序)。time = 纯时间轴排序,零时长行(Start = End)排最前;style = 先按样式分块(块序 = 首次出现顺序),块内按时间排序,块内零时长行置顶;裸 -sort 等价 time。Format: 行与空行位置不动,Comment: 行同样参与排序 |
-mininfo |
可选 | 把 [Script Info] 重写为最小标准形式(ScriptType / Collisions / ScaledBorderAndShadow / PlayResX / PlayResY / Timer),丢弃注释与字幕组元数据;PlayResX / PlayResY 缺失时省略 |
<files>...(位置式) |
可选 | 要处理的 .ass 文件,多个空格分隔;支持通配符 ep*.ass;省略则处理当前目录所有 *.ass(fixed_* 除外) |
-file <name> / -filename <name> |
可选 | 显式指定文件;可重复;带空格的路径需加引号 |
-h / -help / -? / /? |
可选 | 打印用法帮助并退出 |
兼容写法:
/offset、--offset、-skip=keyword、-sort=style等均可。位置式与显式式可混用,但有三条防呆约束:偏移只能给一次(重复报错);-sort显式给出两个不同模式会报错;offset 0且未给-sort/-mininfo时直接报错(无事可做,不会产出与原文件相同的fixed_*)。
:: 1) 整个字幕提前 0.2 秒(不指定样式 = 所有样式)
ASSShift -0.2
ASSShift -0.2 abc.ass
:: 2) 文件名写在 offset 前也可以(.ass 结尾的 token 一律视为文件)
ASSShift abc.ass -0.2
:: 3) 单样式
ASSShift CN -0.2 abc.ass
:: 4) 多样式(空格 / 逗号 / 引号,三种写法等价)
ASSShift CN JP -0.2 abc.ass
ASSShift CN,JP -0.2 abc.ass
ASSShift "CN,JP" -0.2 abc.ass
:: 5) 显式 -offset,适合写进脚本 / 文档
ASSShift CN JP -offset -0.16 abc.ass
:: 6) 延迟 3 秒(位置式与显式式等价)
ASSShift CN JP 3 abc.ass
ASSShift CN JP -offset 3 abc.ass
:: 7) 跳过含关键字的行(含 \pos 需加引号;多关键字命中任一即跳过)
ASSShift CN -0.2 -Skip pos abc.ass
ASSShift CN JP -0.16 -Skip "\pos" abc.ass
ASSShift CN -0.2 -Skip pos -Skip end abc.ass
:: 8) 多文件与通配符
ASSShift CN JP -0.2 ep01.ass ep02.ass ep03.ass
ASSShift CN -0.2 ep*.ass
:: 9) 目录批量:当前目录所有 *.ass(fixed_* 除外)
ASSShift -0.16 -Skip "\pos"
:: 10) 纯时间轴排序(Subresync 逻辑),零时长注释行置顶
ASSShift 0 -sort time abc.ass
:: 裸 -sort 等价于 -sort time
ASSShift 0 -sort abc.ass
:: 11) 按样式分块排序(块序 = 样式首次出现顺序),块内按时间
ASSShift 0 -sort style abc.ass
:: 12) 精简 [Script Info]
ASSShift 0 -mininfo abc.ass
:: 13) 平移 + 分块排序 + 精简,一步到位
ASSShift CN JP -0.16 -sort style -mininfo abc.ass
:: 14) 纯重组:不平移任何时间,只排序 + 精简
ASSShift 0 -sort style -mininfo abc.ass
:: 15) 不经 .cmd,直接调用 ps1(语法相同)
powershell -NoProfile -ExecutionPolicy Bypass -File ASSShift.ps1 CN,JP -offset -0.16 -Skip "\pos" -sort style -mininfo abc.ass样例输出:
ASSShift
Style : CN, JP
Offset : -0.16 seconds
Skip : "\pos"
Sort : style blocks (first-appearance order), timeline within, zero-duration first per block
Info : rewrite [Script Info] to minimal form
Files : abc.ass
abc.ass changed: 116 skipped: 7 sorted: 340 info: cleaned
Done. Files: 1 changed: 116 skipped: 7 sorted: 340
-
输出:每个源文件旁生成
fixed_<原名>.ass;原文件永不修改。 -
目录扫描:不给文件名时,处理当前目录下所有
*.ass,并自动跳过fixed_*(避免叠加处理)。显式给出的文件名按字面处理,不受fixed_*排除限制。 -
样式匹配:区分大小写(与渲染器一致)。样式名是
Dialogue行第 4 个字段;省略样式 = 匹配所有Dialogue行。 -
-Skip匹配:作用于Dialogue行的 Text 字段(第 10 个字段,含{\pos(...)}等特效标签),不区分大小写,是“包含”关系。 -
排序(
-sort time):[Events]段内Dialogue/Comment行按**(零时长 → Start → End → 原始行号)**重排——零时长行(Start = End,字幕组用作注释)聚到最前;同时间的行保持原有相对顺序。 -
排序(
-sort style):按**(样式块序 → 零时长 → Start → End → 原始行号)重排——样式块按该样式在事件中首次出现的顺序**排列(尊重作者原布局,非字母序),块内按时间升序,块内零时长行置顶。 -
排序通用规则:只重排事件行的原有槽位,
Format:行、空行、其他段落一律不动;Comment:行参与排序但永不平移;时间无法解析的行不参与排序(留在原槽位);排序发生在平移之后,使用最终时间,顺序永远与成品时间轴一致。 -
-mininfo:只重写第一个[Script Info]段;白名单 6 键按固定顺序输出,值取自原文件(缺失用默认值;PlayResX/PlayResY缺失则整行省略;ScaledBorderAndShadow规范化为Yes/No;Timer规范化为四位小数);重复键取首个。注意WrapStyle、YCbCr Matrix等不在白名单内会被丢弃(与 Subresync 行为一致;若原文件WrapStyle非 0,丢弃后会回到默认换行方式)。处理前(Aegisub 导出的典型头部):
[Script Info] ; Script generated by Aegisub 9820-cibuilds-8165f1ad5 Title: xxxxxxxx- ScriptType: v4.00+ WrapStyle: 0 PlayResX: 1920 PlayResY: 1080 ScaledBorderAndShadow: yes Original Script: xxx字幕组 YCbCr Matrix: TV.709处理后(
-mininfo):[Script Info] ScriptType: v4.00+ Collisions: Normal ScaledBorderAndShadow: Yes PlayResX: 1920 PlayResY: 1080 Timer: 100.0000 -
时间钳制:负偏移把某行
Start/End推到0:00:00.00之前的,自动钳到0:00:00.00。 -
编码保留:根据 BOM / 内容自动识别 UTF-8、UTF-8 BOM、UTF-16 LE/BE、ANSI,并按原编码回写。
-
只动
Dialogue的时间:Comment行、Format行、[V4+ Styles]段的Style:定义行内容均保持不变。
为什么“offset 是分界线”?
样式名、偏移、文件名三种位置参数并存时,最容易混淆的是“这个纯数字是样式还是偏移”。ASSShift 用类型 + 位置双判据消歧:
- 类型:纯数字 token → 偏移;非纯数字 → 样式或文件名
- 位置:偏移之前的 token 全部当样式,之后的全部当文件名
- 例外:以
.ass结尾的 token 一律是文件——因此ASSShift abc.ass -0.2与ASSShift -0.2 abc.ass都合法
因此 ASSShift CN JP 3 abc.ass 是完全确定的:CN、JP 是样式,3 是偏移,abc.ass 是文件。唯一的死角是“样式名恰好是纯数字”,此时用 -style 3 绕开。
为什么裸 -sort 等价 -sort time?
与 Subresync 的默认重排行为对齐:多数人要的就是“纯时间轴 + 零时长行置顶”。需要分块时显式写 -sort style 即可。-sort 的值只在下一个 token 恰为 time / style 时才被吞掉,所以 -sort abc.ass 不会误吞文件名。
为什么 style 分块序 = 首次出现顺序?
分块排序的本意是还原“字幕作者的块布局”(OP 块、正文块、ED 块……)。按首次出现顺序排列最忠实地保留作者意图;字母序反而会打乱。
确定性保证:两种排序键的末位都是原始行号,即使排序算法稳定性有差异,结果也唯一确定;同时间的行永远保持原有相对顺序。
建议:交互式手敲用位置式(
CN JP -0.2最顺手);写进脚本 / 文档用显式-offset(一眼看懂)。两者完全等价。
技术细节:
.cmd把原始命令行原文通过环境变量ASSSHIFT_CMDLINE整体交给.ps1,由脚本自行分词。这样负数偏移、引号、逗号分隔、-sort可选值等写法在cmd.exe、powershell -File、PowerShell 控制台三种调用方式下行为完全一致。.ps1故意不写param()块,避免-File的参数绑定层把-Skip、-0.2等以-开头的 token 当成参数名而报错。
Q:不加样式会怎样?
A:ASSShift -0.2 = 整个字幕所有 Dialogue 行整体平移;-Skip、-sort、-mininfo 照常生效。
Q:offset 0 是什么意思?为什么报 "nothing to do"?
A:0 表示不平移时间,是纯重组模式,需搭配 -sort / -mininfo 使用。若 0 且两个开关都没给,程序会直接报错退出,避免产出一份与原文件相同的 fixed_*。
Q:-sort 会不会把后面的文件名当成模式值吞掉?
A:不会。只有下一个 token 恰好是 time / style(忽略大小写)时才作为 -sort 的值,其余情况都原样解析。
Q:-Skip 没生效,所有行都被改了?
A:确认写的是 -Skip <关键字>(-skip=keyword 也支持)。注意匹配的是 Text 字段,关键字出现在 Actor / Effect 等字段不会命中。控制台会打印 skipped: N 计数。
Q:多样式写法 CN JP 报错?
A:请使用本仓库最新版 .cmd 与 .ps1。旧版 .cmd 只把前两个参数映射到 -Style / -Offset,会误把第二个样式当偏移报 无法将值"JP"转换为 System.Decimal。
Q:CN,JP(逗号)和 CN JP(空格)一样吗?
A:完全一样。命令行原文整体交给脚本解析,逗号在样式 token 内会被自动拆分。
Q:偏移可以是 1:30 这种时分秒吗?
A:不支持。偏移统一用秒(可带小数与正负号),如 -0.16、3、+0.35。
Q:处理完会覆盖原文件吗?
A:永不。结果写到 fixed_*.ass。如需覆盖,自行把 fixed_* 改名即可。
Q:为什么我的样式没被匹配?
A:样式名匹配区分大小写。若末尾提示 No Dialogue line matched the given styles,请核对 [V4+ Styles] 段里 Style: 定义的精确大小写。
Q:用 Subresync 必须先转 UTF-16 LE,这里需要吗? A:不需要。本工具自动检测 UTF-8 / UTF-8 BOM / UTF-16 LE/BE / ANSI 并按原编码回写,UTF-8 的中日文文件直接处理,不会乱码。
Q:-mininfo 会不会丢掉重要东西?
A:会丢弃白名单之外的所有键(含 ; 注释、Title、Original *、Video *、WrapStyle、YCbCr Matrix),这与 Subresync 的简化行为一致。渲染层面唯一可能有感知差异的是 WrapStyle 非 0 的文件(丢弃后回到默认换行方式);YCbCr Matrix 丢失时播放器会按自身规则猜测。
| 退出码 | 含义 |
|---|---|
0 |
全部成功 |
1 |
用法 / 参数错误(未给偏移、偏移非法、偏移重复、-sort 模式冲突、0 且无事可做等) |
2 |
至少有一个文件处理失败(如文件被占用) |
Apache 2.0 License