差不多去年的這個時候吧,由於項目組的編碼從GBK轉向UTF-8,讓我來負責轉換所有的源檔案,當時frank給了我一個轉換的指令碼,可以過濾檔案類型來轉換,由於是frank自己使用的工具,所以也沒怎麼注意容錯,基本上可以理解成是對某些類型的檔案使用iconv -f gbk -t utf-8 這樣的命令來轉換。後來發現悲劇了,原因是有一些檔案已經是utf-8編碼了,結果在強轉了一次,就亂碼了,因為只有幾個檔案亂碼,所以一開始還沒注意到,直到後來發現的時候,又得一個一個重新轉回去,所以還是挺麻煩的。
最近在用一個公用組件的時候,發現其提供的都是gbk編碼的,所以想著乾脆還是寫一個指令碼來完成這件事情吧,這次吸取了上次的教訓,首先會用file來判斷下檔案的編碼是什麼編碼的(當前只判斷gbk和utf-8),然後根據不同的類型,來設定不同的轉換選項。預設只轉換當前檔案夾下的所有.cpp和.h檔案,當然,路徑和檔案類型,可以分別用-f和-t的參數傳進去。當然,如果你發現有什麼沒有考慮到的地方,還請斧正,謝謝啦。
#!/bin/bashfile_type_list="cpp h"file_path="."#-f:檔案名稱或者目錄名 -t: 檔案類型#如果不傳入參數,預設目錄為目前的目錄,預設轉換檔類型為.h .cpp#example:covert_to_utf8 -f . -t "cpp h"while getopts "t:f:" arg #選項後面的冒號表示該選項需要參數do case $arg in f) echo "f's arg:$OPTARG" file_path=$OPTARG ;; t) echo "t's arg:$OPTARG" file_type_list=$OPTARG ;; ?) echo "unkonw argument" exit 1 ;; esacdoneecho "file_type=" $file_type_list "file_path=" $file_path #如果是普通檔案或者目錄才進行尋找、轉換,其他情況,不轉換if [ -f $file_path -o -d $file_path ];then echo "Begin to Convert $file_path from GBK to UTF-8...."else echo " $file isn't a file or directory,can't convert! " exit;fi#找到普通檔案,然後轉換這些檔案all_file=`find $file_path -type f`;for file in $all_file;do file_type=${file##*.} #echo $file $file_type; if [[ "$file_type_list" != *"$file_type"* ]]; then echo "$file_type not in $file_type_list" continue; fi file_encoding=`file $file | awk -F : '{print $2}' | awk '{print $1}'` #GBK if [ $file_encoding == "ISO-8859" ]; then original_encoding="gbk" #ASCII or UTF-8 elif [ $file_encoding == "ASCII" -o $file_encoding == "UTF-8" ]; then echo "$file encoding $file_encoding is ok, not need convert" continue; #未定義的編碼 else echo "$file error encoding $file_encoding, can't convert" continue; fi iconv -f $original_encoding -t utf-8 $file > $file"_tmp" #判斷是否轉換成功 if [ $? != 0 ]; then echo "covert $file failed!" continue; fi mv $file"_tmp" $file echo "convrt $file success!"doneecho "All file convert done!"