问题:在window上保存ANSI格式文本文件,复制到liunx系统,其中的中文乱码。
常规解决办法
1. 查看文本文件的编码
[root@localhost example]# file -i 7-2.c7-2.c: text/x-c; charset=iso-8859-1
2. 利用iconv命令进行转码
[root@localhost example]# iconv -f iso-8859-1 -t utf-8 7-2.c#include <stdio.h>/*ÀûÓÃÊý×鼯Ëãì³²¨ÄÇÆõÊýÁеÄǰ10¸öÊý¼´ 1,1,2,3,5,...,55 ²¢°´ÕÕÿÐÐ5¸öÊýµÄ¸ñʽÊä³ö*/int main(){int list[10] = {1,1};int i;for(i=2; i<10; i++) {list[i] = list[i-1] + list[i-2];}for(i=0; i<10; i++) {printf("%d\t", list[i]);if ((i+1)%5 == 0) {printf("\n");}}return 0;}
可见,仍然是乱码!!!
这里边的坑
file命令识别文件的编码不正确
我这个文件的正确编码应该是GBK
[root@localhost example]# iconv -f GBK -t utf-8 7-2.c#include <stdio.h>/*利用数组计算斐波那契数列的前10个数即 1,1,2,3,5,...,55 并按照每行5个数的格式输出*/int main(){int list[10] = {1,1};int i;for(i=2; i<10; i++) {list[i] = list[i-1] + list[i-2];}for(i=0; i<10; i++) {printf("%d\t", list[i]);if ((i+1)%5 == 0) {printf("\n");}}return 0;}
两个问题
有没有能够准确识别文件编码的工具?如果没有,能不能自己写一个?
批量转码脚本
# 设置调试参数 │[root@localhost data]# lsset -ueEo pipefail; │7-2.c 7-3.c 7-4.c 7-5.c 7-6.c#读取参数 │[root@localhost data]# bash mutil-iconv.sh -f gbk -t utf-8 data/*.cwhile getopts ":f:t:" OPT; do │bash: mutil-iconv.sh: No such file or directorycase "$OPT" in │[root@localhost data]# cd ..f) │[root@localhost script]# bash mutil-iconv.sh -f gbk -t utf-8 data/*.cfrom_code=$OPTARG; │data/7-2.c data/7-3.c data/7-4.c data/7-5.c data/7-6.c;; │/usr/bin/iconv: illegal input sequence at position 53t) │/usr/bin/iconv: illegal input sequence at position 40to_code=$OPTARG; │/usr/bin/iconv: illegal input sequence at position 34;; │/usr/bin/iconv: illegal input sequence at position 39?) │/usr/bin/iconv: illegal input sequence at position 39echo "arg err" >&2; │[root@localhost script]# bash mutil-iconv.sh -f gbk -t utf-8 data/*.cexit 1; │data/7-2.c data/7-3.c data/7-4.c data/7-5.c data/7-6.c;; │/usr/bin/iconv: illegal input sequence at position 39esac │[root@localhost script]#done │# 检查必要的参数 │if [ -z "$from_code" ]; then │echo "必须传入源文件的编码" >&2; │exit 1; │fi │if [ -z "$to_code" ]; then │echo "必须传入要转换的编码" >&2; │exit 1; │fi │# 读取文件列表 │shift $((OPTIND-1)); │# 读入数组中 │file_list=($@); │# 循环处理 │for item in ${file_list[*]} │do │#echo /usr/bin/iconv -f "$from_code" -t "$to_code" -o "$item" "$item"; │/usr/bin/iconv -f "$from_code" -t "$to_code" -o "$item" "$item"; │done
写脚本时遇到的问题-总结
getopts命令
命令也是人用程序写出来的,基本思维是一样的!!!
getopts命令,语法格式
getopts optstring variable [arg]
getopts的作用是,取出-开头的参数列表。optstring就是要取的参数列表,比如”fh”,即
getopts “fh” key。怎么工作的?说白了,看看$1是不是带有-,如果没有命令终止。如果有-, 再看看是否在”fh”中。如果不是报错,终止命令,如果事继续看看$2。就这样,我们自己写也可能这样写。
getopts命令用到了几个全局变量
OPTIND : 当前取到第几个了,也就是${!OPTIND}
OPTARG: “f:”,后面加个冒号表示该参数需要带值,获取的的值就存入OPTARG中
“:fh”,最前边放冒号表示静默模式,如果命令出错不返回错误信息
arg 默认 $@,可以指定。比如 getopts “fh:” var aa cc bb。如下:
[root@localhost script]# getopts "hf:" OPT -h │[root@localhost script]# echo $OPT │h │[root@localhost script]# getopts "hf:" OPT aa bb │[root@localhost script]# echo $OPT │? │[root@localhost script]#
一种调试方式
#echo /usr/bin/iconv -f "$from_code" -t "$to_code" -o "$item" "$item";# 可以打印命令最终执行的样子
