开源简繁转换工具OpenCC在技术文档写作中的批处理应用

中文简繁转换是个值得研究的课题。如果只是偶尔有一两篇长度为几千字的文档需要转换,直接用微软Offce Word 自带的简繁转换功能就行了,最多再花点时间人工校对下。但是,在规模较大的技术文档写作任务中,用Offce Word的话显然效率很低,得另寻他法。

还是先描述一下我需要处理的情形吧。假设我在某个文件夹下放置了十几个xml文本文件,它们都包含了简体中文内容;我需要在另一个文件夹下维护另一套对应的文档,只不过它们都是繁体中文的。由于专门术语的要求,我必须维护一个简繁术语对比清单(即自定义的词典),在进行简繁转换时先根据清单转一次(利用开发人员定制的脚本),然后利用其它工具(如Office Word)再转一次。实际上,Word也是支持自定义词典的,那为何我不把第一个步骤使用的术语表导入到Word中,省去一个步骤呢?其实我试过了,貌似是当自定义术语表太长时,导入Word中会报错。况且,即便解决了导入术语的问题,也没法解决另外一个更麻烦的问题:用Word的话,每次只能转换一个文档。

《也谈中文的简繁转换》这篇日志中,我提到过OpenCC这个开源的中文简繁转换工具。不过那篇文章并没有对OpenCC多加介绍,主要是因为当时我还没有留意到其强悍之处:支持命令行操作。命令行操作意味着有很可能我可以利用批处理脚本来进行批量转换操作。使用opencc –help命令,可以查看OpenCC的可用参数:

==============传说中的分割线============

Options:
-i [file], –input=[file]   Read original text from [file].
-o [file], –output=[file]  Write converted text to [file].
-c [file], –config=[file]  Load configuration of conversion from [file].
-v, –version               Print version and build information.
-h, –help                  Print this help.

With no input file, reads standard input and writes converted stream to standard output.
Default configuration (zhs2zht.ini) will be loaded if not set.

============传说中的分割线=============

由以上帮助说明可以得知,如果不手动指定配置文件的话,默认用的就是zhs2zht.ini,即对应图形界面的那个“简体到繁体”选项。

简转繁的四个选项对应配置文件如下(参考这里):

  • 简体到繁体  zhs2zht.ini
  • 简体到台湾标准 zhs2zhtw_p.ini
  • 简体到台湾标准(只转异体字) zhs2zhtw_v.ini
  • 简体到台湾标准(只转常用词汇) zhs2zhtw_vp.ini

举个例子,我要把一个简中文档zh_cn.xml转化为繁中版zh_tw.xml,转换方式为“简体到台湾标准”,则输入的命令应为:

opencc -i zh_cn.xml -o zh_tw.xml -c zhs2zhtw_p.ini

现在的问题是我在一个文件夹中有十几个xml文件要转换,如何批量处理呢?作为仅仅懂得最基本copy和del命令的批处理小白,我表示鸭梨山大。Google一下,发现有高手(galaxy5566@北大中文論壇)制作了一个修订版的词库,还顺带提供了两个快捷转换的批处理脚本(原文在此)。仔细研究了其中一个的“多檔案-批處理轉換”脚本后,我发现稍微修改一下即可应用到我的实际工作环境中。

原始的批处理代码主要内容如下:

===========传说中的分割线========

@echo off
@set dir1=cntemp\
@set dir2=mulit-trad\
@cd /d %~dp0
@if not exist %dir1% md %dir1%
@if not exist %dir2% md %dir2%
@copy *.xml %dir1%
@for /f “delims=” %%i in (‘dir %dir1%*.* /b’) do @opencc.exe –input=”%dir1%%%i” –output=”%dir2%%%i”
@echo.
@echo Done!
@echo.
@pause

===========传说中的分割线========

这个批处理程序的原理是:先定义两个文件夹(dir1和dir2),用户把待转换的源文件放进其中一个文件夹(dir1)后,执行此脚本,转换后输出的(同名)文件自动放到另外一个文件夹(dir2)。顺便提一句,该脚本也是使用默认的配置文件zhs2zht.ini,不过我们仍然可以手动指定所需的配置文件。

在改造这个脚本前,得先分析一下我的实际应用情形:

如上图所示,我有多套文档(book1、2、3、4)要维护,每套文档又分为简体(zh_cn)和繁体(zh_tw)两个目录,每个源文档目录下有若干xml文档(chapter01.xml、chapter02.xml、chapter03.xml等)。这些目录之间的相对位置是固定的,因此我要考虑如何更有效地利用相对路径来处理。我决定把OpenCC序目录放在document的同一层路径下。以处理book1的情形为例,在OpenCC程序目录下放置了这么一个批处理文件:

============传说中的分割线=========

@echo if error message appears please check whether u converted ur file to UTF-8 format
@echo.
@echo off
@set dir1=..\document\book1\zh_cn\
@set dir2=..\document\book1\zh_tw\
@cd /d %~dp0
@echo Start to convert…
@for /f “delims=” %%i in (‘dir %dir1%chapter*.xml /b’) do @opencc.exe –input=”%dir1%%%i” –output=”%dir2%%%i” -c customization.ini
@echo.
@echo. Finished!
@pause

============传说中的分割线=========

对比一下“galaxy5566@北大中文論壇”提供的批处理程序,我的主要修改说明如下:

1)因为我的源文档目录是相对固定的,所以我直接指定dir1和dir2分别为简繁两个目录(这个例子中使用了相对路径),且无需考虑建立目录的问题。

2)我的zh_cn目录下并非所有文件都需要转换,只有那些文件名以chapter开头的xml文档才需要。所以我把 @for /f “delims=” %%i in (‘dir %dir1%*.* /b’) 改成了 (‘dir %dir1%chapter*.xml /b’)。

3) -c customization.ini 是我手动指定的配置文件。

4)按照常规的文档工作流程,一般是更新完简体中文版后才会去更新繁体中文版。编译过程序的童鞋应该都知道clean操作的概念,这里我也可以考虑在转换之前用del命令将旧版繁体(chapter开头的)xml文档全部删除。因为前面已经定义过输出目标文件夹dir2的具体路径了,所以这里的del直接引用%dir2%就行了,命令如下,供参考:

@echo Delete old version in the zh_tw folder…
@del %dir2%\chapter*.xml /q

不过我没有将这个步骤加进去,因为我的实际应用情形有所不同。我们使用CVS来管理这些xml文档,那么一个简单的del命令显然是没法将不再需要的(繁体版)xml文档从CVS中删除。鉴于已经提交到CVS的文档会有一个绿色对勾标记,那实际上我完全不必使用del命令来删除旧版的繁体xml文件,只需直接转换并覆盖之,然后看一下繁体版目录中哪些文件依然处于已提交状态的(说明这些文件没有被覆盖,即对应的简体版源文件已经不存在了),手动cvs remove之即可。

对于book1而言,我修改过的这个批处理只涉及到两个变量,即dir1和dir2。如果要book2等其他文档进行处理,只需对应改一下dir1和dir2即可。所有此类批处理命令都统一放在OpenCC程序文件夹下,也便于管理和使用。

如果想一次性转换完多个目录下的文件怎么办呢?很简单,依次指定dir1、dir2、dir3、dir4……然后为每个目录下的转换操作写一遍for命令,合并到一个批处理文件中就行了。

关于OpenCC的配置文件写法规则,可以参考其作者的说明。简单说,它通过依次加载不同的词典来进行转换。词典有两种格式,即.ocd和.txt。一般人不会去折腾.ocd词典,不过定制一下.txt词典倒是还算方便。仔细观察可以发现,OpenCC默认提供的.txt词典一般是最后加载的。打开这些词典看看还能进一步发现,它们是“繁体到繁体”的格式(本文提到所有的情形都基于“简转繁”),即在经过若干.ocd字典转成繁体后,通过一个附加的.txt词典进行纠正。注意到这点的话,如果你手头上已有简繁对比的自定义清单需要整理成OpenCC可用的词典,就得稍微加工一下了。此外,当前最新版OpenCC内部编码使用的是Linux的换行符(参考这里),所以如果在Windows系统下自定义.txt词典时需要注意,可以利用EmEditor将自定义词典另存为新文件,只需选择换行方式为“仅LF(UNIX)”。

使用此方法之前,即便是在我已经很熟练操作的情况下,每次转换一个xml文件也要花1分钟左右时间。这样连续操作几十次,在多个目录之间来回切换,还得注意别搞错源文件和目标文件,这是个什么概念?大家稍微发挥一下想象力就可以体会到这是多么无聊的事情了。如果用本文的方法来操作,一两秒即可转换完几十个xml文件。

写完本文,突然就想起这么一句话来了:懒惰是人类进步的动力,勤奋是实现偷懒的途径。啥意思?你懂的,如果你真的看完本文的话……

“开源简繁转换工具OpenCC在技术文档写作中的批处理应用”的15个回复

  1. 个人觉得,你倒是可以去利用makefile在管理文件方面的强项,做同样的事情,效率可能会更高点。windows下的想用makefile的话,装个cygwin,算是不错的选择,这样就可以充分利用众多的linux下的各种工具了。
    这样,即使以后有更多需求,实现和维护起来,也都更加容易和高效。

    偶目前编译20+个docbook,就是通过makefile去管理的,效果还是不错的,哈哈。

    个人建议,仅供参考,呵呵。

      1. 关于makefile的话,简单说就是,其最核心的逻辑是文件的依赖关系,主要用于各种项目的管理,常用于源码类项目的编译过程的控制。
        此处,你可以利用makefile来管理你这几十个xml文件(和未来可能出现的更多的文件)。

        makefile之于你:

        坏处是:
        1.学习曲线会比你已经熟悉的windows下的bat脚本要陡峭些
        2.在windows下用makefile,还需要顺带搞定cygwin(不是必须的,但是推荐的做法)

        好处是:
        1.一旦学会了,在未来会发挥出极大的效用,你会发现比bat强大多了,好用多了,即以后处理更多的xml文档,更加复杂的需求,用makefile+cygwin,会比bat更加容易,更加高效,扩展性更好

        总的说,算是吃了点苦,学了makefile+cygwin,以后日子过得就happy多了。

        关于cygwin,可以参考我写的介绍:
        http://www.crifan.com/files/doc/docbook/soft_dev_basic/release/html/soft_dev_basic.html#cygwin

        关于makefile的学习,网上最流行的是那个pdf版本的“跟我一起写Makefile”,不过个人推荐你直接去看这个在线版的:
        跟我一起写Makefile:MakeFile介绍 – Ubuntu中文
        http://wiki.ubuntu.org.cn/index.php?title=%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:MakeFile%E4%BB%8B%E7%BB%8D&variant=zh-cn
        其版面逻辑更清晰,循序渐进,容易看懂。

        关于如何从头搭建你的makefile环境,需要的话,偶可以帮你一起弄,呵呵。

        1. Mark,受教啦!看来有空还是要探索下Win之外的世界~其实很多年前用过一阵Ubuntu,当时没坚持下来……要是当初一直用下来了,也许现在进一步学习就顺手多了。

          1. 上次用ubuntu,貌似是四五年前的事情了,现在估计变得翻天覆地啦~

  2. 您好,我直接把词语左右对照的文字复制到了EmEditor,然后自定义.txt词典时选择了换行方式为“仅LF(UNIX),但是为什么最后使用程序时还是说配置错误?是哪里有问题呢?

    1. “直接复制”?我觉得应该是这样操作,你手动复制一个现有的OpenCC字典来用,然后手动把你的术语粘贴进去。换句话说,应该是在EmEditor选择了正确换行方式后,才进行文本编辑,而不是粘贴完文本再来改换行方式。

      1. 求救啊,为什么我发现我的OpenCC里面没有txt 字典,都是ocd格式的……您能发一个样本给我吗?

          1. 要不留个下载链接……现在确实找不到……没法下手……

          2. 多谢多谢,我那个版本太低了,现在终于没问题了,感谢!

回复 Daniel 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注