GNU gettext自动化处理和操作PO文件命令行工具集用法详解

PO 文件处理不再头疼:探索 GNU gettext 的命令行利器

文章目录

如果你参与过软件的国际化(I18n)和本地化工作,尤其是使用 GNU gettext 框架,那么你一定对 .po 文件(Portable Object 文件)不陌生。这些文件是翻译的载体,将原始的英文消息与各种目标语言的翻译关联起来,相关阅读GNU gettext国际化PO文件格式详解

最初,翻译工作可能主要围绕使用 Emacs 的 PO mode 或其他 PO 编辑器进行手动编辑。但随着项目变大、翻译文件增多,手动处理会变得效率低下且容易出错。幸好,GNU gettext 工具集不仅仅包含 xgettext(用于提取字符串模板,详细用法参考《xgettext 用法详解》)和 msgfmt(用于生成二进制 MO 文件),它还提供了一整套强大的命令行工具,专门用于自动化和批量处理 PO 文件。

这些工具能帮助你合并、过滤、检查、更新和管理 PO 文件,让你的本地化流程更加顺畅。接下来,详细了解这些强大的命令行工具吧!

1. msgcat: 合并与连接 PO 文件

想象一下,你有多个 PO 文件,也许来自不同的模块,或者你只是想将一些翻译片段合并起来。msgcat 就是你的不二之选。

它的基本作用是将多个 PO 文件串联起来,形成一个单独的输出文件。它还能智能地合并相同的消息条目。

常用选项:

  • -o file--output-file=file:将结果写入指定文件,而不是标准输出。
  • --sort-output:按字母顺序对输出的消息条目进行排序。
  • --sort-by-file:按文件位置对输出的消息条目进行排序。请注意,使用此选项可能会使译者理解消息的上下文变得更加困难。

示例:合并 file1.pofile2.pocombined.po

msgcat -o combined.po file1.po file2.po

如果你想合并多个零散的 compendium 文件到一个文件 update.po,可以这样做(虽然这个例子后面还涉及到 msgmergemsgattrib):

msgcat --use-first -o update.po compendium1.po compendium2.po file.po

然后可以结合 msgmergemsgattrib 进行进一步处理。

2. msggrep: 根据条件过滤消息

有时候你只关心 PO 文件中的一部分消息,比如只处理来自某个源文件的字符串,或者只查找包含特定文本的消息。msggrep 可以根据各种条件从 PO 文件中提取消息子集。

常用选项:

  • -o file--output-file=file:将结果写入指定文件.
  • --location string:提取来自指定源文件或位置的消息.
  • -N location:类似于 --location.
  • -t string--text string:提取包含指定原始字符串 (msgid) 的消息.

示例:提取来自源文件 src/getopt.c 的消息到 compendium.po:

msggrep --location src/getopt.c -o compendium.po file.po

示例:提取来自源文件 gnulib-lib/error.cgnulib-lib/getopt.c 的消息:

msggrep -N gnulib-lib/error.c -N gnulib-lib/getopt.c input.po

示例:提取原始字符串中包含“Please specify”的消息:

msggrep --text "Please specify" input.po

3. msgfilter: 对翻译应用任意命令

这是一个非常强大的工具,它允许你对 PO 文件中的翻译文本msgstr 部分)应用任何能够读取标准输入并写入标准输出的命令。这对于执行批量文本转换非常有用,比如调整字符编码或执行基于正则表达式的替换。

示例:将德语翻译中的“ß”替换为“ss”(适用于瑞士德语):

msgconv -t UTF-8 de.po | msgfilter sed -e 's/ß/ss/g'

这个例子首先使用 msgconvde.po 转换为 UTF-8 编码,然后通过管道将其输入到 msgfiltermsgfilter 再将每个翻译文本传递给 sed 命令进行替换。

示例:使用 recode-sr-latin 命令转换西里尔塞尔维亚语翻译:

msgfilter recode-sr-latin < sr.po

4. msguniq: 移除重复的消息条目

在处理多个来源或多次合并的 PO 文件时,可能会出现同一个原始字符串 (msgid) 重复出现多次的情况。msguniq 工具可以帮助你找到并合并这些重复的条目,只保留一个唯一的条目。

常用选项:

  • -o file--output-file=file:将结果写入指定文件.
  • -u--unique:只打印那些只出现一次的消息条目(等同于 --less-than=2).
  • -> number--more-than=number:打印出现次数多于指定次数的消息(默认为 1).

示例:处理 input.po 并将去重后的结果输出到标准输出:

msguniq input.po

5. msgcomm: 查找共有的消息

如果你想知道两个或多个 PO 文件之间有哪些共同的翻译消息,msgcomm 工具可以帮你实现。

6. msgcmp: 比较 PO 文件

msgcmp 工具用于比较两个 PO 文件,通常用于检查翻译文件是否与其对应的模板文件 (.pot) 同步。它可以报告哪些消息在翻译文件中缺失或过时。

7. msgattrib: 根据属性过滤或修改消息

PO 文件中的每个消息条目都可以有一些属性,比如“模糊”(fuzzy)标记(表示该翻译可能需要复审)或是否已翻译。msgattrib 工具可以根据这些属性来过滤消息,或者修改这些属性。

常用选项:

  • --translated:只保留已翻译的条目.
  • --untranslated:只保留未翻译的条目.
  • --fuzzy:只保留标记为“模糊”的条目.
  • --no-fuzzy:排除标记为“模糊”的条目.
  • --obsolete:只保留已过时的条目.
  • --no-obsolete:排除已过时的条目.
  • --file file:根据指定文件中的消息条目进行过滤.
  • --set-fuzzy:将匹配的消息标记为“模糊”.
  • --clear-fuzzy:移除匹配消息的“模糊”标记.

示例:从 file.po 中提取所有已翻译且未标记为模糊的条目:

msgattrib --translated --no-fuzzy file.po

示例:结合 msgmerge 更新文件后,移除过时的条目:

msgmerge update.po file.pot | msgattrib --no-obsolete > file.po

8. msgen: 创建英文翻译目录

对于以英语为母语的项目维护者来说,有时需要一个“英文翻译”,其翻译内容与原始字符串完全相同。msgen 工具可以接受一个 PO 模板文件 (.pot) 或一个 PO 文件作为输入,并创建一个新的 PO 文件,其中所有未翻译条目的 msgstr 都被填充为其对应的 msgid

注意:msginit --no-translator --locale=en 也能完成类似任务,但 msgen 更侧重于消息条目本身的处理。

示例:基于模板文件 package.pot 创建一个英文 PO 文件 en.po

msgen package.pot -o en.po

9. msgexec: 对所有翻译执行命令

msgexec 工具允许你对 PO 文件中的每个翻译文本执行一个指定的命令。这个命令会接收翻译文本作为标准输入。这与 msgfilter 类似,但 msgexec 更像是对每个单独的翻译条目执行操作,而不是对整个文件流进行过滤。

示例:对 PO 文件中的每个翻译文本执行一个脚本 check_translation.sh

msgexec check_translation.sh input.po

10. libgettextpo: 编写自己的 PO 处理程序

如果上述标准工具不能满足你的复杂需求,GNU gettext 还提供了一个 C 语言库 libgettextpo。这个库提供了用于解析、操作和写入 PO 文件内存结构的函数,让你可以编写自己的定制化 PO 文件处理程序。

头文件是 <gettext-po.h>。它提供了如 po_file_read 读取文件到内存结构、po_file_write 将内存结构写回文件、po_message_t 数据类型表示一个消息条目、以及访问和修改消息属性(如 msgidmsgstr)的函数(如 po_message_msgid, po_message_set_msgid, po_message_msgstr, po_message_set_msgstr 等)。这个库支持多线程安全地操作不同的数据对象。

总结

GNU gettext 工具集远不止提取和编译翻译文件。msgcat, msggrep, msgfilter, msguniq, msgcomm, msgcmp, msgattrib, msgen, msgexec 这些命令行工具,以及 libgettextpo 库,共同构成了一个强大的 PO 文件处理框架。它们能显著提高本地化工作的效率,减少手动错误,让你能更专注于翻译本身的质量。

下次你需要处理大量的 PO 文件时,不妨试试这些工具,它们可能会成为你的得力助手!

希望这篇博客文章对你有所帮助!如果你有任何问题或使用经验,欢迎在下方评论区交流!


也可以看看