[原创] Linux 下如何批量修改文本文件的编码

操作系统环境:

CentOS 7 64bit

背景

之前抓取了一个四大名著原文的网站,但是发现其文件编码格式不是UTF-8, 而是GB18030。这样对于使用起来有很多不方便的地方。于是想对下载下来的文本文件进行批量编码格式转换。

开始编码转换

既然要进行编码转换,当然首先要知道原始文件的编码格式。
刚开始最先想到的是用file命令查看文件编码:

1
2
$ file hlm.htm
hlm.htm: HTML document, ISO-8859 text, with very long lines, with CRLF line terminators

但是发现显示的文件编码格式不对,应该是GB18030而不上面显示的ISO-8859
由于 Google 了一下,发现有个工具叫uchardet可以查看文本文件的格式,于是就尝试了下:

安装uchardet

1
$ sudo yum -y install uchardet

查看文件编码格式

1
2
$ uchardet index.html
GB18030

果然这个是靠谱的。接下来就开始写 shell 进行批量转换吧。
说明:
有人可能要问了,既然你都知道了文件的编码格式,那为什么还需要用工具查看文件编码呢?
原因很多,最主要是就是有了这个工具就可以使用它配合其它 shell 命令进行全自动转换了。详见后文。

由于原来 html 文件中的charset设置的是GB2312,因此首先将其改成UTF-8

将所有 html 文件的charset修改成UTF-8

1
2
3
4
5
6
$ sed -r -i s/charset=gb2312/charset=utf-8/g      *.htm*
$ sed -r -i s/charset=gb2312/charset=utf-8/g hlm/*.htm*
$ sed -r -i s/charset=gb2312/charset=utf-8/g jpm/*.htm*
$ sed -r -i s/charset=gb2312/charset=utf-8/g sgyy/*.htm*
$ sed -r -i s/charset=gb2312/charset=utf-8/g shz/*.htm*
$ sed -r -i s/charset=gb2312/charset=utf-8/g xyj/*.htm*

批量编码格式转换 GB18030 -> UTF-8

1
2
3
4
5
6
$ for file in      *.htm*; do iconv -f gb18030 -t utf-8 "$file" -o "$file"; done
$ for file in hlm/*.htm*; do iconv -f gb18030 -t utf-8 "$file" -o "$file"; done
$ for file in jpm/*.htm*; do iconv -f gb18030 -t utf-8 "$file" -o "$file"; done
$ for file in sgyy/*.htm*; do iconv -f gb18030 -t utf-8 "$file" -o "$file"; done
$ for file in shz/*.htm*; do iconv -f gb18030 -t utf-8 "$file" -o "$file"; done
$ for file in xyj/*.htm*; do iconv -f gb18030 -t utf-8 "$file" -o "$file"; done

iconv是文本编码转换工具。若你之前没有安装过,可以使用yum命令进行安装。
至此,批量编码格式转换完成。

自动检测源文件编码并完成转换

由于有了charset工具,因此你可以实现文本编码格式自动检测,从而不需要手动指定源文本编码格式,只需要指定转换后的格式即可。
此方法最适用于源文本有多种不同编码格式的情况。

1
$ for file in *.htm*; do iconv -f $(uchardet "$file") -t utf-8 "$file" -o "$file"; done

参考文献
https://stackoverflow.com/a/34502845

坚持原创及高品质技术分享,您的支持将鼓励我继续创作!