97. 独立于语言的输出(国际化)


当您编写 awk 脚本来打印报告时,您可以使用 print 命令指定报告页眉和页脚信息。 您可以用英语定义页眉和页脚静态值。如果您想执行其他语言的报告输出怎么办?

您最终可能会将此 awk 脚本复制到另一个 awk 脚本并修改所有打印语句以使静态值以适当的值显示。 可能更简单的方法是在这里使用国际化,您可以使用相同的 awk 脚本,但在运行时更改输出的静态值。

当您有一个庞大的程序,但由于某种原因您最终会频繁更改打印的静态输出时,此技术也很有用。 或者您可能希望用户通过将静态显示文本更改为自己的内容来自定义 awk 输出。

这个简单的示例展示了在 awk 中实现内部化的 4 个高级步骤。

创建一个文本域并将其绑定到 awk 程序应在其中查找文本域的目录。 在此示例中,它设置为当前目录。

$ cat iteminfo.awk
BEGIN {
    FS=","
    TEXTDOMAIN = "item"
    bindtextdomain(".")
    print _"START_TIME:" strftime("%a %b %d %H:%M:%S %Z%Y",systime());
    printf "%-3s\t", _"Num";
    printf "%-10s\t", _"Description"
    printf "%-10s\t", _"Type"
    printf "%-5s\t", _"Price"
    printf "%-3s\n", _"Qty"
    printf _"-----------------------------------------------------\n"
}
{
    printf "%-3d\t%-10s\t%-10s\t$%-.2f\t%03d\n",$1,$2,$3,$4,$5
} 

注意:上面的例子中所有允许自定义的字符串前面都有_。 在字符串前面添加 _(下划线)不会改变其打印方式,即打印时不会出现任何问题,如下所示。
$ awk -f iteminfo.awk items.txt
START_TIME:Sat Mar 05 09:15:13 PST 2011
Num	Description	Type      	Price	Qty
-----------------------------------------------------
101	HD Camcorder	Video     	$210.00	010
102	Refrigerator	Appliance 	$850.00	002
103	MP3 Player	Audio     	$270.00	015
104	Tennis Racket	Sports    	$190.00	020
105	Laser Printer	Office    	$475.00	005

生成可移植目标文件(扩展名 .po),如下所示。 请注意,您还可以使用 "-W gen-po" 代替 --gen-po

$ gawk --gen-po -f iteminfo.awk > iteminfo.po

$ cat iteminfo.po
#: iteminfo.awk:5
msgid "START_TIME:"
msgstr ""

#: iteminfo.awk:6
msgid "Num"
msgstr ""
#: iteminfo.awk:7
msgid "Description"
msgstr ""
#: iteminfo.awk:8
msgid "Type"
msgstr ""
#: iteminfo.awk:9
msgid "Price"
msgstr ""
#: iteminfo.awk:10
msgid "Qty"
msgstr ""
#: iteminfo.awk:11
msgid
"-----------------------------------------------------\n"
""
msgstr "" 

现在,修改此可移植目标文件并相应地更改消息字符串。 例如,如果您想调用 "Report Generated on:"(而不是 "START_TIME:"),请编辑 「iteminfo.po」 文件并将 msgid 正下方的 msgstr 更改为 "START_TIME:"

$ cat iteminfo.po
#: iteminfo.awk:5
msgid "START_TIME:"
msgstr "Report Generated On:"

注意:在此示例中,其余 msgstr 字符串留空。

使用 msgfmt 命令创建消息对象文件(从可移植对象文件)。

如果 「iteminfo.po」 的 msgstr 全部为空,则不会生成任何消息对象文件,如下所示。

$ msgfmt -v iteminfo.po
0 translated messages, 7 untranslated messages.

由于我们创建了一个消息翻译,因此它将创建 「messages.mo」 文件。

$ msgfmt -v iteminfo.po
1 translated message, 6 untranslated messages.
$ ls -1 messages.mo
messages.mo

将此消息对象文件复制到您应在当前目录下创建的消息目录。

$ mkdir -p en_US/LC_MESSAGES

$ mv messages.mo en_US/LC_MESSAGES/item.mo 

注意:注意:目标文件名应与我们在原始 awk 文件的 TEXTDOMAIN 变量中指定的名称匹配。 TEXTDOMAIN = "item"

现在您会看到它不再显示 "START TIME:"。 它应该在输出中显示翻译后的字符串 "Report Generation On:"

$ gawk -f iteminfo.awk items.txt
Report Generated On:Sat Mar 05 09:19:19 PST 2011 
Num	Description	Type      	Price	Qty
-----------------------------------------------------
101	HD Camcorder	Video     	$210.00	010
102	Refrigerator	Appliance 	$850.00	002
103	MP3 Player	Audio     	$270.00	015
104	Tennis Racket	Sports    	$190.00	020
105	Laser Printer	Office    	$475.00	005