许功盖:中文字的替换
现在许多人都使用 UTF-8 的环境了。但是由于一些包袱,无法完完全全的转移到 UTF-8 环境,例如一些旧文件、旧程序。幸好 Vim 对各地区性编码都有支持,包括了我们的 Big-5 码。
处理 Big-5 码,最让人头疼的就是著名的『许功盖』的问题,这些字,含有一些一般环境不被认同的字符,会被当做其他解释,这时处理时就会误解为其他含意,而不是原来的中文字了。
例如,我们想把文章中的『许』替换成『么』,我们用 sed/awk/perl/ruby 来试试看(以下是在 Big-5 环境):
[edt1023@lgj ~]$ sed -i -e 's/许/么/' bg5.txt
sed: 1: "s/许/么/": unterminated substitute in regular expression
[edt1023@lgj ~]$ awk 'gsub(/许/,"么") {print}' bg5.txt
awk: non-terminated regular expression 许/,"么") ... at source line 1
context is
﹥﹥﹥ ﹤﹤﹤
awk: syntax error at source line 1
missing )
awk: bailing out at source line 1
[edt1023@lgj ~]$ perl -pi -e 's/许/么/' bg5.txt
Substitution replacement not terminated at -e line 1.
[edt1023@lgj ~]$ ruby -pi -e 'gsub(/许/,"么")' bg5.txt
-e:1: unterminated string meets end of file
-e:1: parse error, unexpected tSTRING_END, expecting
tSTRING_CONTENT or tREGEXP_END or tSTRING_DBEG or
tSTRING_DVAR
看到了吗?通通不行!
因为这些程序是以 single byte 的方式来处理,并不认得我们 Big-5 码的 double byte 的编码方式,会从中去切开来解析,碰到特殊字符就会被解读成另外一个意义去了。
Vim 可以支持 locale,他会视 locale 的设定来变换该使用的编码环境,我们就来使用 vim 试试看:
vim --noplugin -esn -c %s/许/么/g -c wq! bg5.txt
他是 OK 的,能很顺利的处理 Big-5 中文,不怕『许功盖』的问题。但是这有一个缺点,那就是不接受 sh pattern,例如 *.txt 之类的,来进行多档处理。不过,在 sh 下,我们可以利用 sh for loop 来达成多档处理的目的:
for f in *.txt
do
vim --noplugin -esn -c %s/许/么/g -c wq! $f
done
这样就成了。vim 后所接的参数主要是不让他进入 vim 编辑器,也可以去处理档案,并把一些不必要的东西不去加载,改用 ex mode,来加快他的启动速度。Vim 也是可以拿来这样用喔!:-D
【更正:Tue Sep 5 18:29:38 CST 2006】
Ruby 可以指定编码的方式来避开『许功盖』的问题:
ruby -Ke -pi -e 'gsub(/么/,"么")' bg5.txt
感谢 luke(小路)的指正。python 虽然也可以指定编码,但他是以批注的方式来表现,无法用于命令行的一行文行形式。perl 也是可以指定编码,但只对 stdin/stdout 有效,要使用 pipe 的方式来达成,无法就地编辑的方式来达成。