如何用sed识别MediaInfo输出的文本块并解决无关块输出问题
问题原因分析
你的sed命令逻辑存在漏洞:
- 命令中
/^Text #/!{H;$!d}会把所有非Text #开头的行(包括General、Video、Audio块的全部内容)持续追加到保持空间,直到遇到第一个Text #开头的行。 - 此时执行
x会将保持空间里累积的所有前置块内容,与当前Text块内容合并到模式空间。如果这个Text块包含English,就会连带输出前面的General、Video、Audio内容。 - 后续的Text块虽会覆盖保持空间,但第一个匹配的块已经把前置内容带出来了。
修正后的sed命令
要准确分割MediaInfo的块,需以每个块的起始行(如General、Video #N、Text #N这类行)作为分隔点,遇到新块就重置保持空间:
sed -n ' /^[A-Z][a-z]* #\?/{ x /English/p s/.*// x } H ${x;/English/p} ' input.txt
逻辑说明:
- 匹配到任意块的起始行时,先交换保持空间与模式空间,检查是否含English并输出,随后清空保持空间,再交换回来将当前块起始行存入保持空间。
- 非起始行直接追加到保持空间。
- 最后一行处理完成后,再检查一次保持空间的内容。
批量处理字幕的更优方案
直接处理MediaInfo纯文本易出错,建议用它的结构化输出功能,配合MKVToolNix实现批量操作:
1. 提取英文字幕ID
用MediaInfo的Inform参数直接输出字幕ID与语言:
mediainfo --Inform="Text;%ID%|%Language%\n" yourfile.mkv | grep -i "english" | cut -d'|' -f1
批量遍历目录下MKV文件的写法:
for file in *.mkv; do english_sub_ids=$(mediainfo --Inform="Text;%ID%|%Language%\n" "$file" | grep -i "english" | cut -d'|' -f1 | tr '\n' ',') english_sub_ids=${english_sub_ids%,} # 去掉末尾多余逗号 echo "$file: 英文字幕ID为 $english_sub_ids" done
2. 清理非英文字幕并生成新文件
用mkvmerge仅保留视频、音频和英文字幕:
mkvmerge -o "clean_$file" --subtitle-tracks "$english_sub_ids" "$file"
3. 提取英文字幕为SRT文件
用mkvextract导出指定ID的字幕:
for id in $english_sub_ids; do mkvextract tracks "$file" "$id:${file%.mkv}_eng_$id.srt" done
将上述步骤整合到脚本中,即可一次性完成批量处理。
内容的提问来源于stack exchange,提问作者anothers
相关产品推荐
相关产品推荐

