Correct source file encoding with one liner

Tue 08 March 2011
  • 把戏 tags:
  • bash
  • shell published: true comments: true

Amoeba项目最早的代码可以追溯到2008年了,其中有多个作者贡献代码,因为一直在Windows下开发,所以没有使用UTF8编码,最近大家统一到UTF8,遇到了代码编码不正确的问题。

于是我们需要统一解决一下这个问题: iconv -f gbk -t utf8 -o ConnectionManager.java ConnectionManager.java

这样可以把gbk编码的源文件转换为UTF8,原地转换。

推广到整个代码目录,用find和xargs做,xargs通过-I来制定一个占位符。 find . -name "*.java" -type f -perm +600 -print | xargs -I _ iconv -f gbk -t utf8 -o _ -c _

结果发现iconv运行中报了错,进一步检查发现一部分代码正常转换了,另一部分却乱码了。原来,两个作者的代码分别是gbk和gb2312,这iconv转换的时候两种编码并不兼容。这就麻烦了,必须对代码分别处理才可以,区别代码的编码,暂时就用Java源文件里的作者名字。又看了一下find似乎没有对文件内容过滤的条件,不过不要紧,我们可以用xargs做: find . -name "*.java" -type f -perm +600 -print | xargs -I _ sh -c 'grep -q hexianmao _ && iconv -f gb2312 -t utf8 -o _ -c _ '

对这位hexianmao作者的代码,我们利用grep进程的返回值来进行判断。grep的-q参数相当于>/dev/null。这里有一个tricky的地方,再xargs里我们不能直接用&&来组合命令,不过可以通过sh -c这样的方式,并且其中的占位符会被xargs合适地替换掉。

这样执行之后,这位作者的gb2312代码就被成功转换了。而另一部分作者的gbk代码也可以用同样方式解决了。