1.enconv文件名編碼轉換,好比要將一個GBK編碼的文件轉換成UTF-8編碼,操做以下
enconv -L zh_CN -x UTF-8 filename enconv -L GB2312 -x UTF-8 test.txt
2.convmv文件名編碼轉換:
從Linux往windows拷貝文件或者從windows往Linux拷貝文件,有時會出現中文文件名亂碼的狀況,出現這種問題的緣由是由於,windows的文件名中文編碼默認爲GBK,而Linux中默認文件名編碼爲UTF8,因爲編碼不一致,因此致使了文件名亂碼的問題,解決這個問題須要對文件名進行轉碼。在Linux中專門提供了一種工具convmv進行文件名編碼的轉換,能夠將文件名從GBK轉換成UTF-8編碼,或者從UTF-8轉換到GBK。
yum -y install convmv
下面看一下convmv的具體用法:
sudo convmv -f gbk -t utf-8 -r –notest /home
經常使用參數: -r 遞歸處理子文件夾 --notest 真正進行操做,請注意在默認狀況下是不對文件進行真實操做的,而只是試驗。 --list 顯示全部支持的編碼 --unescap 能夠作一下轉義,好比把%20變成空格 好比咱們有一個utf8編碼的文件名,轉換成GBK編碼,命令以下: convmv -f UTF-8 -t GBK --notest utf8編碼的文件名 這樣轉換之後"utf8編碼的文件名"會被轉換成GBK編碼(只是文件名編碼的轉換,文件內容不會發生變化)
就是將/home目錄下原來文件名是gbk編碼方式的所有改成utf-8格式的。這裏 -f 後面爲原來的編碼方式,-t 後面是要更改成的編碼方式, -r 表示這個目錄下面的全部文件, –notest 表示立刻執行,而不是僅僅測試而已。另外這命令好像要root才能執行,所以要加上 sudo。
3.iconv文件內容編碼轉換:
iconv轉換,好比將一個UTF-8 編碼的文件轉換成GBK編碼 iconv -f GBK -t UTF-8 file1 -o file2 iconv -f GB2312 -t UTF-8 test.txt -o test2.txt 下載地址: ftp://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.8.tar.gz
-f爲原來的編碼方式,-t 爲輸出文件的編碼方式, -o表示輸出文件名,這利用outfile表示,最後跟上要更改編碼方式的文件名sourcefile 。
經過這兩個工具,中文文件亂碼的問題終於解決。
4.unix2dos,dos2unix轉換:
使用od -c -t x1 abc.txt 查看文本文件裏的特殊字符,DOS/Windows使用/r/n做爲行尾符,Unix使用/n做爲行尾符:
unix2dos < unix.txt > dos.txt 將Unix格式的純文本文件轉換成DOS/Windows格式的純文本文件
dos2unix < dos.txt > unix.txt 將DOS/Windows格式的純文本文件轉換成Unix格式的純文本文件
若是你在openoffice裏編輯,是徹底兼容的,若是你在vi裏 出現/M等符號,可使用 tr 或 sed工具過濾掉
在Linux下正常換行的文字,到了Windows下後,再也不換行。
在Windows下換行時,有兩個字符:回車(/r)和換行(/n)。但在Linux下,只有一個換行(/n)
可以使用unix2dos和dos2unix命令進行格式的轉換:
參數:
-k 保持輸出文件和輸入文件的日期時間戳不變
-o file 默認模式 . 將file轉換,並輸出到file
-n infile outfile 新模式. 轉換infile, 並輸出到outfile
1. unix2dos 假設用vi新建一文本文件,輸入123456 [root@centos test]# ls -l a.txt -rw-r--r-- 1 root root 7 Jan 7 21:31 a.txt [root@centos test]# hexdump -c a.txt 0000000 1 2 3 4 5 6 /n 0000007 [root@centos test]# unix2dos -n a.txt b.txt unix2dos: converting file a.txt to file b.txt in DOS format ... [root@centos test]# ls -l total 8 -rw-r--r-- 1 root root 7 Jan 7 21:31 a.txt -rw------- 1 root root 8 Jan 7 21:34 b.txt [root@centos test]# hexdump -c a.txt 0000000 1 2 3 4 5 6 /n 0000007 [root@centos test]# hexdump -c b.txt 0000000 1 2 3 4 5 6 /r /n 0000008 b.txt是轉換後的DOS下的文件 2. dos2unix [root@centos test]# dos2unix -n b.txt c.txt dos2unix: converting file b.txt to file c.txt in UNIX format ... [root@centos test]# ls -l total 12 -rw-r--r-- 1 root root 7 Jan 7 21:31 a.txt -rw------- 1 root root 8 Jan 7 21:34 b.txt -rw------- 1 root root 7 Jan 7 21:38 c.txt [root@centos test]# hexdump -c b.txt 0000000 1 2 3 4 5 6 /r /n 0000008 [root@centos test]# hexdump -c c.txt 0000000 1 2 3 4 5 6 /n 0000007 c.txt是轉換後unix下的文本文件
5. enca (若是你的系統中沒有安裝這個命令,能夠用sudo yum install -y enca 安裝 )查看文件編碼
$ enca filename
filename: Universal transformation format 8 bits; UTF-8 CRLF line terminators 須要說明一點的是,enca對某些GBK編碼的文件識別的不是很好,識別時會出現: Unrecognized encoding
5.vim中fileencoding設置文件編碼,見文章末尾
od命令 用戶一般使用od命令查看特殊格式的文件內容。經過指定該命令的不一樣選項能夠以十進制、八進制、十六進制和ASCII碼來顯示文件。 語法:od [選項] 文件… 命令中各選項的含義: - A 指定地址基數,包括: d 十進制 o 八進制(系統默認值) x 十六進制 n 不打印位移值 - t 指定數據的顯示格式,主要的參數有: c ASCII字符或反斜槓序列 d 有符號十進制數 f 浮點數 o 八進制(系統默認值爲02) u 無符號十進制數 x 十六進制數 除了選項c之外的其餘選項後面均可以跟一個十進制數n,指定每一個顯示值所包含的字節數。 說明:od命令系統默認的顯示方式是八進制,這也是該命令的名稱由來(Octal Dump)。但這不是最有用的顯示方式,用ASCII碼和十六進制組合的方式能提供更有價值的信息輸出。
od 和 hexdump 顯示文件內容或流的八進制、十六進制或其餘編碼的字節。它們對於訪問或可視地檢查文件中不能直接顯示在終端上的字符頗有用。 s-w8每行只用8個字節顯示: [tim@L gx]$ od -Ad -tax1 -w8 a.txt 0000000 1 2 3 4 5 6 cr nl 31 32 33 34 35 36 0d 0a 0000008 a b c d e f cr nl 61 62 63 64 65 66 0d 0a 0000016 h e l l o , w o 68 65 6c 6c 6f 2c 77 6f 0000024 r l d cr nl 72 6c 64 0d 0a -j2字符方式輸出test內容,跳過前兩個字節: [tim@L gx]$ od -Ad -tax1 -j2 a.txt 0000002 3 4 5 6 cr nl a b c d e f cr nl 33 34 35 36 0d 0a 61 62 63 64 65 66 0d 0a 6 0000018 l l o , w o r l d cr nl 6c 6c 6f 2c 77 6f 72 6c 64 0d 0a 0000029 -N2只顯示兩個字節,用字符方式顯示: [tim@L gx]$ od -Ad -tax1 -N2 a.txt 0000000 1 2 31 32 S
使用wc命令來進行文本內容統計: 指令名稱:wc 語法:wc [clw] file 說明:按照不一樣選項來統計字節數、字數、行數等。具體應用實例請自行 'man wc'來查看。 例子:統計當前目錄下文件的個數,使用命令 ls -l | wc -l ps:該指令的參數選項比較少,曾有人使用C語言實現了wc的功能,你也能夠試試哦!
使用sort命令對文本內容進行排序: 指令名稱:sort 語法:sort [-bcdfimMnr][-o<輸出文件>][-t<分隔字符>][+<起始欄位>-<結束欄位>][--help][--verison][文件] 選項解釋:(更多說明請自行man sort) -n:按照數目排序,number -r:降序排序 -u:去除重複項
使用uniq命令對文本進行重複列的查看和刪除: 指令名稱:uniq 語法:uniq [選項] file 說明:顯示文本中行的某些特性。 選項解釋:(更多說明請自行 man uniq) -c:在行首加上該行出現的次數,count的縮寫。 -d:只顯示重複行 -u:顯示不重複的行
使用diff命令對文本進行比較操做: 指令名稱:diff 語法:diff [選項] file1 file2 說明:diff是以逐行的方式,對兩個文件進行異同的操做。 選項解釋:(更多說明請自行 man diff) -i:忽略大小寫的差別 -b:忽略空格的差別
使用du命令統計目錄或文件佔用磁盤空間大小: 指令名稱:du 語法:du [選項] 目錄或文件 選項解釋:(更多說明請自行 man du) -k/m/g: 以kb、mb、gb顯示大小 du -S | sort -n 列出佔用空間最大的目錄 -sh:只查看指定的目錄,子目錄不查看
使用cut命令來提取想要的數據: 指令名稱:cut 語法:cut [選項] 文件 用法說明: -b:截取字節 -c:截取字符 cut -c1-15 表示截取從第一列到15列的內容 cut -c1-4,8- 表示截取1到4列的內容,還有從第八列到最後的內容 -f:截取字段 cut -f1 -d‘:' 表示截取第一列,是以:做為分隔符來截取的 cut -f1- -s:表示截取中間的分隔符為Tab鍵分割的文本 ps:截取中文的時候須要注意中文字符是做為2個英文字符組成的。
使用dd命令來測試磁盤速度、創建新文件: 指令名稱:dd 指令說明:從指定位置copy數據到指定輸出位置 應用實例:bs指定每次操做塊的大小,count指定操做的次數 創建2M大小的文件。 # dd if=/dev/zero of=/home/test/2M.txt bs=1024 count=2048 同樣的,測試磁盤讀寫速度 # dd if=/dev/zero of=/home/rwspeed.ret bs=1024 count=1048576 複製備份系統 # dd if=/home/test/my_fiter of=/其餘設備 bs=512 count=256 ps:windows平臺上也存在著創建指定大小文件的命令,是 fsutil 。
使用nice命令來調整程序執行的優先級: 指令名稱:nice 指令說明:調整進程的優先級 應用實例:Linux進程的優先級是從 -20 ~ +20 的,數字越小,優先級越高,也就是佔用CPU的時間越多。 普通用戶只能下降程序的優先級,root用戶能夠提升/下降進程的優先級。 # nice 查看默認的優先級 # nice ./a.out 默認執行,給a.out增長10個優先級,也就是分配更少的cpu時間。 # nice -n -20 a.out 為a.out執行最高的優先級 Unix/Linux上面的命令不少,這是無數黑客和全世界的程序員們的智慧結晶。 熟練的掌握和使用系統提供的命令,每每會事倍功半。這裡只列出了不多的一部份, 其它的命令能夠參考該網站的介紹,或者是找本介紹詳細的書籍來看看。
文件編碼轉換html
convert_encoding.py 基於Python的文本文件轉換工具;python
decodeh.py 提供算法和模塊來談測字符的編碼;linux
1)設置文件集合,即要對哪些文件進行操做,可使用通配符,好比我一般是對 C/C++ 源程序進行編碼轉換nginx
:args *.h *.cppgit
2)給出要在每一個文件上執行的命令,這裏是轉換編碼:github
:argdo set fenc=utf-8 | update 算法
首先,咱們先要知道控制Linux OS 的語言環境變量是 $LANG和$LC_ALL,要解決亂碼的狀況咱們只須要把上述的兩個變量正確設置便可.
亂碼分兩種狀況:
1.終端(純shell界面)的亂碼
vi /etc/profile
export LC_ALL="zh_CN.GB18030:zh_CN.GB2312:zh_CN.GBK:zh_CN:en_US.UTF-8:en_US:en:zh:zh_TW:zh_CN.BIG5"
保存退出,reboot系統便可..
2.X-window(圖形界面)的亂碼
vi /etc/sysconfig/i18n
LANG="zh_CN.GB18030:zh_CN.GB2312:zh_CN.GBK:zh_CN:en_US.UTF-8:en_US:en:zh:zh_TW:zh_CN.BIG5"
LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN.GBK:zh_CN:en_US.UTF-8:en_US:en:zh:zh_TW:zh_CN.BIG5"
保存reboot便可...
因爲中文的字符集編碼不少,我本身也不是十分清楚彼此的兼容性如何,因此就儘量的找了不少種不一樣的編碼都寫了上去,你們也能夠本身篩選下,總的解決思路就是修改控制環境參數的變量,增長OS所支持的字符集(前提要內核上存在該字符,不然須要編譯內核)...
正在開發的WEB系統是部署在RED HEAD 。
RH版本信息:
LSB Version: :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: RedHatEnterpriseServer
Description: Red Hat Enterprise Linux Server release 5 (Tikanga)
Release: 5
Codename: Tikanga
-------------------------------
locale 信息
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=
---------------------------------
由於程序目錄有若干文件要讀出來顯示在頁面上,文件名爲中文名
我使用File.list()方法獲得了文件名列表,但是顯示出來的都是亂碼。
new String(filename.getBytes("utf-8"),"GBK");
new String(filename.getBytes("iso-8859-1"),"GBK");
new String(filename.getBytes(),GBK");
都不起做用,
使用 System.getProperty("file.encoding") 得出的是"utf-8"
另外,使用 ls 命令查看的時候,是亂碼,使用 ls --show-control-chars 命令就能顯示中文名(控制檯)
添加 locale, 估計你的系統不支持gbk字符集。
ubuntu下是 vi /var/lib/locales/supported.d/local
加完後 locale-gen一下, 從新刷新字符集緩存。
shell
vim 編碼設置
和全部的流行文本編輯器同樣,Vim 能夠很好的編輯各類字符編碼的文件,這固然包括UCS-二、UTF-8 等流行的Unicode 編碼方式。然而不幸的是,和不少來自 Linux 世界的軟件同樣,這須要你本身動手設置。
Vim 有四個跟字符編碼方式有關的選項,encoding、fileencoding、fileencodings、termencoding (這些選項可能的取值請參考 Vim 在線幫助 :help encoding-names),它們的意義以下:
* encoding: Vim 內部使用的字符編碼方式,包括 Vim 的 buffer (緩衝區)、菜單文本、消息文本等。默認是根據你的 locale選擇.用戶手冊上建議只在 .vimrc 中改變它的值,事實上彷佛也只有在.vimrc 中改變它的值纔有意義。你能夠用另一種編碼來編 輯和保存文件,如你的vim的encoding爲utf-8,所編輯的文件採用cp936編碼,vim會自動將讀入的文件轉成utf-8(vim的能讀懂 的方式),而當你寫入文件時,又會自動轉回成cp936(文件的保存編碼).
* fileencoding: Vim 中當前編輯的文件的字符編碼方式,Vim 保存文件時也會將文件保存爲這種字符編碼方式 (無論是否新文件都如此)。
* fileencodings: Vim自動探測fileencoding的順序列表,啓動時會按照它所列出的字符編碼方式逐一探測即將打開的文件的字 符編碼方式,而且將 fileencoding 設置爲最終探測到的字符編碼方式。所以最好將Unicode 編碼方式放到這個列表的最前面,將拉丁語系 編碼方式 latin1 放到最後面。
* termencoding: Vim 所工做的終端 (或者 Windows 的 Console 窗口) 的字符編碼方式。若是vim所在的 term與vim編碼相同,則無需設置。如其否則,你能夠用vim的termencoding選項將自動轉換成term 的編碼.這個選項 在 Windows 下對咱們經常使用的 GUI 模式的 gVim 無效,而對 Console 模式的Vim 而言就是 Windows 控制檯的代碼 頁,而且一般咱們不須要改變它。ubuntu
~/.vimrc 文件中添加如下內容:vim
set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936
這樣,就可讓vim自動識別文件編碼(能夠自動識別UTF-8或者GBK編碼的文件),其實就是依照fileencodings提供的編碼列表嘗試,若是沒有找到合適的編碼,就用latin-1(ASCII)編碼打開
Vim 的多字符編碼工做方式
1. Vim 啓動,根據 .vimrc 中設置的 encoding 的值來設置 buffer、菜單文本、消息文的字符編碼方式。
2. 讀取須要編輯的文件,根據 fileencodings 中列出的字符編碼方式逐一探測該文件編碼方式。並設置 fileencoding 爲探測到的,看起來是正確的 (注1) 字符編碼方式。
3. 對比 fileencoding 和 encoding 的值,若不一樣則調用 iconv 將文件內容轉換爲encoding 所描述的字符編碼方 式,而且把轉換後的內容放到爲此文件開闢的 buffer 裏,此時咱們就能夠開始編輯這個文件了。注意,完成這一步動做須要調用外部 的 iconv.dll(注2),你須要保證這個文件存在於 $VIMRUNTIME 或者其餘列在 PATH 環境變量中的目錄裏。
4. 編輯完成後保存文件時,再次對比 fileencoding 和 encoding 的值。若不一樣,再次調用 iconv 將即將保存 的 buffer 中的文本轉換爲 fileencoding 所描述的字符編碼方式,並保存到指定的文件中。一樣,這須要調用 iconv.dll由 於 Unicode 可以包含幾乎全部的語言的字符,並且 Unicode 的 UTF-8 編碼方式又是很是具備性價比的編碼方式 (空間消耗 比 UCS-2 小),所以建議 encoding 的值設置爲utf-8。這麼作的另外一個理由是 encoding 設置爲 utf- 8 時,Vim 自動探測文件的編碼方式會更準確 (或許這個理由纔是主要的 。咱們在中文 Windows 裏編輯的文件,爲了兼顧與其餘軟件的兼容 性,文件編碼仍是設置爲 GB2312/GBK 比較合適,所以 fileencoding 建議設置爲 chinese (chinese 是個別名, 在 Unix 裏表示 gb2312,在 Windows 裏表示cp936,也就是 GBK 的代碼頁)。
3.在Vim中查看,轉換文件編碼
vim中查詢修改文件編碼格式
set fileencoding
查看如今文本的編碼
:set fenc=編碼
轉換當前文本的編碼爲指定的編碼
:set enc=編碼
以指定的編碼顯示文本,但不保存到文件中。
這裏的「編碼」常見爲gbk utf-8 big5 cp936
:set ff?
查看當前文本的模式類型,通常爲dos,unix
:set ff=dos
設置爲dos模式
也能夠用一下方式轉換爲unix模式
:%s/^M//g
等同於:set ff=unix
五、FAQ
爲何在Vim中一次只能刪除半個漢字?
由於encoding設置錯誤,把encoding設置爲cp936就能夠解決此問題。在Unix環境下Vim會根據locale來設置默認的encoding,若是沒有正確設置locale而且沒有設置encoding就會一次只能刪除半個漢字。
VIM爲何不能輸入繁體字?
把euc-cn或者GB2312改成cp936就能夠了。euc-cn是GB2312的別名,不支持繁體漢字。cp936是GBK的別名,是GB2312的超集,能夠支持繁體漢字。
VIM爲何提示不能轉換?
由於在編譯Vim時沒有加入iconv選項,從新編譯Vim才能解決。
如何打開一個GBK編碼的文件並另存爲UTf-8編碼?
保存文件時運行命令|:set fileencoding=utf-8|就能夠了。
:set fileencoding ,gb2312不轉utf8不能使用egrep 便可顯示文件編碼格式。 若是你只是想查看其它編碼格式的文件或者想解決 用Vim查看文件亂碼 的問題,那麼你能夠在 ~/.vim rc 文件中添加如下內容: set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936 這樣,就可讓vim自動 識別文件編碼(能夠自動識別UTF-8或者GBK編碼的文件),其實就是依照fileencodings提供的編碼列表嘗試,若是沒有找到合適的編碼,就用latin-1(ASCII)編碼打開。
出現^M(\r)(回車符號),緣由是:
輸入 :set ff=unix 後,儲存該文件檔案便可。
vim文件編碼轉換:在Vim中直接進行轉換文件編碼,好比將一個文件轉換成utf-8格式:set fileencoding=utf-8
vim 編碼方式選項(encoding、fileencoding、fileencodings、termencoding介紹)
* encoding: Vim 內部使用的字符編碼方式,包括 Vim 的 buffer (緩衝區)、菜單文本、消息文本等。默認是根據你的locale選擇.用戶手冊上建議只在 .vimrc 中改變它的值,事實上彷佛也只有在.vimrc 中改變它的值纔有意義。你能夠用另一種編碼來編輯和保存文件,如你的vim的encoding爲utf-8,所編輯的文件採用cp936編碼,vim會 自動將讀入的文件轉成utf-8(vim的能讀懂的方式),而當你寫入文件時,又會自動轉回成cp936(文件的保存編碼).
* fileencoding: Vim 中當前編輯的文件的字符編碼方式,Vim 保存文件時也會將文件保存爲這種字符編碼方式 (無論是否新文件都如此)。
* fileencodings: Vim自動探測fileencoding的順序列表,啓動時會按照它所列出的字符編碼方式逐一探測即將打開的文件的字符編碼方式,而且將 fileencoding 設置爲最終探測到的字符編碼方式。所以最好將Unicode 編碼方式放到這個列表的最前面,將拉丁語系編碼方式 latin1 放到最後面。
* termencoding: Vim 所工做的終端 (或者 Windows 的 Console 窗口) 的字符編碼方式。若是vim所在的term與vim編碼相同,則無需設置。如其否則,你能夠用vim的termencoding選項將自動轉換成term 的編碼.這個選項在 Windows 下對咱們經常使用的 GUI 模式的 gVim 無效,而對 Console 模式的Vim 而言就是 Windows 控制檯的代碼頁,而且一般咱們不須要改變它。
好了,解釋完了這一堆容易讓新手犯糊塗的參數,咱們來看看 Vim 的多字符編碼方式支持是如何工做的。
1. Vim 啓動,根據 .vimrc 中設置的 encoding 的值來設置 buffer、菜單文本、消息文的字符編碼方式。
2. 讀取須要編輯的文件,根據 fileencodings 中列出的字符編碼方式逐一探測該文件編碼方式。並設置 fileencoding 爲探測到的,看起來是正確的 (注1) 字符編碼方式。
3. 對比 fileencoding 和 encoding 的值,若不一樣則調用 iconv 將文件內容轉換爲encoding 所描述的字符編碼方式,而且把轉換後的內容放到爲此文件開闢的 buffer 裏,此時咱們就能夠開始編輯這個文件了。注意,完成這一步動做須要調用外部的 iconv.dll(注2),你須要保證這個文件存在於 $VIMRUNTIME 或者其餘列在 PATH 環境變量中的目錄裏。
4. 編輯完成後保存文件時,再次對比 fileencoding 和 encoding 的值。若不一樣,再次調用 iconv 將即將保存的 buffer 中的文本轉換爲 fileencoding 所描述的字符編碼方式,並保存到指定的文件中。一樣,這須要調用 iconv.dll因爲 Unicode 可以包含幾乎全部的語言的字符,並且 Unicode 的 UTF-8 編碼方式又是很是具備性價比的編碼方式 (空間消耗比 UCS-2 小),所以建議 encoding 的值設置爲utf-8。這麼作的另外一個理由是 encoding 設置爲 utf-8 時,Vim 自動探測文件的編碼方式會更準確 (或許這個理由纔是主要的 ;)。咱們在中文 Windows 裏編輯的文件,爲了兼顧與其餘軟件的兼容性,文件編碼仍是設置爲 GB2312/GBK 比較合適,所以 fileencoding 建議設置爲 chinese (chinese 是個別名,在 Unix 裏表示 gb2312,在 Windows 裏表示cp936,也就是 GBK 的代碼頁)。
在 Vim 中,有四個與編碼有關的選項,它們是:fileencodings、fileencoding、encoding 和 termencoding。在實際使用中,任何一個選項出現錯誤,都會致使出現亂碼。所以,每個 Vim 用戶都應該明確這四個選項的含義。下面,咱們詳細介紹一下這四個選項的含義和做用。
1 encoding
encoding 是 Vim 內部使用的字符編碼方式。當咱們設置了 encoding 以後,Vim 內部全部的 buffer、寄存器、腳本中的字符串等,全都使用這個編碼。Vim 在工做的時候,若是編碼方式與它的內部編碼不一致,它會先把編碼轉換成內部編碼。若是工做用的編碼中含有沒法轉換爲內部編碼的字符,在這些字符就會丟失。所以,在選擇 Vim 的內部編碼的時候,必定要使用一種表現能力足夠強的編碼,以避免影響正常工做。
因爲 encoding 選項涉及到 Vim 中全部字符的內部表示,所以只能在 Vim 啓動的時候設置一次。在 Vim 工做過程當中修改encoding 會形成很是多的問題。若是沒有特別的理由,請始終將 encoding 設置爲 utf-8。爲了不在非 UTF-8 的系統如 Windows 下,菜單和系統提示出現亂碼,可同時作這幾項設置: set encoding=utf-8 set langmenu=zh_CN.UTF-8 language message zh_CN.UTF-8 2 termencoding termencoding 是 Vim 用於屏幕顯示的編碼,在顯示的時候,Vim 會把內部編碼轉換爲屏幕編碼,再用於輸出。內部編碼中含有沒法轉換爲屏幕編碼的字符時,該字符會變成問號,但不會影響對它的編輯操做。若是 termencoding 沒有設置,則直接使用encoding 不進行轉換。 舉個例子,當你在 Windows 下經過 telnet 登陸 Linux 工做站時,因爲 Windows 的 telnet 是 GBK 編碼的,而 Linux 下使用 UTF-8 編碼,你在 telnet 下的 Vim 中就會亂碼。此時有兩種消除亂碼的方式:一是把 Vim 的 encoding 改成 gbk,另外一種方法是保持 encoding 爲 utf-8,把 termencoding 改成 gbk,讓 Vim 在顯示的時候轉碼。顯然,使用前一種方法時,若是遇到編輯的文件中含有 GBK 沒法表示的字符時,這些字符就會丟失。但若是使用後一種方法,雖然因爲終端所限,這些字符沒法顯示,但在編輯過程當中這些字符是不會丟失的。 對於圖形界面下的 GVim,它的顯示不依賴 TERM,所以 termencoding 對於它沒有意義。在 GTK2 下的 GVim 中,termencoding 永遠是 utf-8,而且不能修改。而 Windows 下的 GVim 則忽略 termencoding 的存在。 3 fileencoding 當 Vim 從磁盤上讀取文件的時候,會對文件的編碼進行探測。若是文件的編碼方式和 Vim 的內部編碼方式不一樣,Vim 就會對編碼進行轉換。轉換完畢後,Vim 會將 fileencoding 選項設置爲文件的編碼。當 Vim 存盤的時候,若是 encoding 和fileencoding 不同,Vim 就會進行編碼轉換。所以,經過打開文件後設置 fileencoding,咱們能夠將文件由一種編碼轉換爲另外一種編碼。可是,由前面的介紹能夠看出,fileencoding 是在打開文件的時候,由 Vim 進行探測後自動設置的。所以,若是出現亂碼,咱們沒法經過在打開文件後從新設置 fileencoding 來糾正亂碼。 4 fileencodings 編碼的自動識別是經過設置 fileencodings 實現的,注意是複數形式。fileencodings 是一個用逗號分隔的列表,列表中的每一項是一種編碼的名稱。當咱們打開文件的時候,VIM 按順序使用 fileencodings 中的編碼進行嘗試解碼,若是成功的話,就使用該編碼方式進行解碼,並將 fileencoding 設置爲這個值,若是失敗的話,就繼續試驗下一個編碼。 所以,咱們在設置 fileencodings 的時候,必定要把要求嚴格的、當文件不是這個編碼的時候更容易出現解碼失敗的編碼方式放在前面,把寬鬆的編碼方式放在後面。 例如,latin1 是一種很是寬鬆的編碼方式,任何一種編碼方式獲得的文本,用 latin1 進行解碼,都不會發生解碼失敗——固然,解碼獲得的結果天然也就是理所固然的「亂碼」。所以,若是你把 latin1 放到了 fileencodings 的第一位的話,打開任何中文文件都是亂碼也就是理所固然的了。 如下是滇狐推薦的一個 fileencodings 設置: set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1 其中,ucs-bom 是一種很是嚴格的編碼,非該編碼的文件幾乎沒有可能被誤判爲 ucs-bom,所以放在第一位。 utf-8 也至關嚴格,除了很短的文件外(例如許多人津津樂道的 GBK 編碼的「聯通」被誤判爲 UTF-8 編碼的經典錯誤),現實生活中通常文件是幾乎不可能被誤判的,所以放在第二位。 接下來是 cp936 和 gb18030,這兩種編碼相對寬鬆,若是放前面的話,會出現大量誤判,因此就讓它們靠後一些。cp936 的編碼空間比 gb18030 小,因此把 cp936 放在 gb18030 前面。 至於 big五、euc-jp 和 euc-kr,它們的嚴格程度和 cp936 差很少,把它們放在後面,在編輯這些編碼的文件的時候必然出現大量誤判,但這是 Vim 內置編碼探測機制沒有辦法解決的事。因爲中國用戶不多有機會編輯這些編碼的文件,所以咱們仍是決定把 cp936 和 gb18030 前提以保證這些編碼的識別。 最後就是 latin1 了。它是一種極其寬鬆的編碼,以致於咱們不得不把它放在最後一位。不過惋惜的是,當你碰到一個真的 latin1 編碼的文件時,絕大部分狀況下,它沒有機會 fall-back 到 latin1,每每在前面的編碼中就被誤判了。不過,正如前面所說的,中國用戶沒有太多機會接觸這樣的文件。 若是編碼被誤判了,解碼後的結果就沒法被人類識別,因而咱們就說,這個文件亂碼了。此時,若是你知道這個文件的正確編碼的話,能夠在打開文件的時候使用 ++enc=encoding 的方式來打開文件,如: :e ++enc=utf-8 myfile.txt 5 fencview 根據前面的介紹,咱們知道,經過 Vim 內置的編碼識別機制,識別率是很低的,尤爲是對於簡體中文 (GBK/GB18030)、繁體中文 (Big5)、日文 (euc-jp) 和韓文 (euc-kr) 之間的識別。而對於普通用戶而言,肉眼看出一個文件的編碼方式也是很不現實的事情。所以,滇狐強烈推薦水木社區的 mbbill 開發的 fencview 插件。該插件使用詞頻統計的方式識別編碼,正確率很是高。點擊這裏 下載。
vim對文件的編解碼—encoding,fileencoding,fileencodings
vim對於文件的編解碼有三個參數,分別是encoding、fileencoding,fileencodings,下面說的應該能夠解決絕大多數的問題了。
一、支持中文編碼的基礎
要更好地支持中文編碼須要兩個特性:+multi_byte和+iconv,能夠用|:version|命令檢查當前使用的Vim是否支持,不然的話須要從新編譯。
二、影響中文編碼的設置項
Vim中有幾個選項會影響對多字節編碼的支持:
encoding(enc):encoding是Vim的內部使用編碼,encoding的設置會影響Vim內部的Buffer、消息文字等。在Unix環境下,encoding的默認設置等於locale;Windows環境下會和當前代碼頁相同。在中文Windows環境下encoding的默認設置是cp936(GBK)。
fileencodings(fencs):Vim在打開文件時會根據fileencodings選項來識別文件編碼,fileencodings能夠同時設置多個編碼,Vim會根據設置的順序來猜想所打開文件的編碼。
fileencoding(fenc):Vim在保存新建文件時會根據fileencoding的設置編碼來保存。若是是打開已有文件,Vim會根據打開文件時所識別的編碼來保存,除非在保存時從新設置fileencoding。
termencodings(tenc):在終端環境下使用Vim時,經過termencoding項來告訴Vim終端所使用的編碼。
termencodings(tenc):在終端環境下使用Vim時,經過termencoding項來告訴Vim終端所使用的編碼。
三、Vim中的編碼轉換
Vim內部使用iconv庫進行編碼轉換,若是這幾個選項所設置的編碼不一致,Vim就有可能會轉換編碼。打開已有文件時會從文件編碼轉換到encoding所設置的編碼;保存文件時會從encoding設置的編碼轉換到fileencoding對應的編碼。常常會看到Vim提示[已轉換],這是代表Vim內部做了編碼轉換。終端環境下使用Vim,會從termencoding設置的編碼轉換到encoding設置的編碼。
能夠用|:help encoding-values|列出Vim支持的全部編碼。
四、具體應用環境的設置
只編輯GBK編碼的文件
set fileencodings=cp936
set fileencoding=cp936
set encoding=cp936
只編輯UTF-8編碼的中文文件
set fileencodings=utf-8
set fileencoding=utf-8
set encoding=cp936 或者 set encoding=utf-8
同時支持GBK和UTF-8編碼
set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=utf-8
set encoding=cp936 或者 set encoding=utf-8
若是在終端環境下使用Vim,須要設置termencoding和終端所使用的編碼一致。例如:
set termencoding=cp936 或者 set termencoding=utf-8
Windows記事本編輯UTF-8編碼文件時會在文件頭上加上三個字節的BOM:EFBBBF。若是fileencodings中設置ucs-bom的目的就是爲了可以兼容用記事本編輯的文件,不須要的話能夠去掉。Vim在保存UTF-8編碼的文件時會去掉BOM。去掉BOM的最大好處是在Unix下可以使用cat a b>c來正確合併文件,這點常常被忽略。
下載的文件名「亂碼」各平臺的解決方法,echo 文件名亂碼 | iconv -t latin1 | iconv -f gb
提及「亂碼」,沒遇到過的電腦用戶多是極少的,尤爲在國內中文環境下。暴露年齡的「燙燙燙」系列亂碼已經絕跡,現現在遇到的每每是相似「%E9%AB%98%E9%A2%91」和「èªå¨é£è±è½»ä¼¼æ¢¦」的字符串。本文就這兩種亂碼狀況分別給出解決方法。
首先應該說明的是,本文所說的方法是在出現文件名亂碼狀況下,如何恢復文件名的正確中文名稱,並不是一勞永逸地避免亂碼的出現。這是因爲下載文件名稱亂碼的出現,每每是系統、瀏覽器、網站三方面因素共同影響致使的,錯綜複雜。想要避免亂碼的出現,只能根據具體的狀況,對我的的系統或瀏覽器作出針對特定網站的調整配置。
%E9類型亂碼
這種狀況每每是因爲網站和瀏覽器之間存在兼容性問題致使的,我在 macOS 英文系統上使用 Firefox 下載網盤中的文件時就遇到過,這些形如「%E9%AB%98%E9%A2%91」的字符串其實是文件名的 URL 編碼。下面介紹各系統平臺上的解決方法。
macOS 系統
macOS系統自帶強大的自動化支持,如 Automator 和 AppleScript。這裏,我使用 Automator 編寫了一個文件服務,使用方法:
首先,下載「♲ 文件名 UrlDecode.workflow.zip」,解壓後雙擊安裝。
而後,右鍵單擊須要處理的文件,選擇服務子菜單中的 ♲ 文件名 UrlDecode,完畢。
使用演示
這個服務不須要網絡,支持批量處理多個文件或文件夾。用 Automator 打開會發現其原理很簡單,只有「運行 Shell 腳本」的操做,其中的 Shell 代碼爲:
Windows 系統
相比 macOS, Windows 缺少友好、易用的自動化工具。在安裝 Python 後,能夠利用批處理命令調用代碼python -c "import sys, urllib as ul; print ul.unquote_plus(sys.argv[1])"
進行文件名修復。可是考慮到該過程略複雜,該類亂碼出現頻率較低,因此這裏不提供工具,而是介紹如何利用在線網站解決問題。
- 複製文件的亂碼名稱,如「%E9%AB%98%E9%A2%91」。
- 打開在線解碼網站。粘貼到輸入框,點擊下方的「UrlDecode 解碼」,便可獲得對應中文。
- 複製解碼後的中文,重命名文件。
Linux 系統
Linux 各發行版和桌面環境的差別較大,且用戶折騰能力較強,這裏就不給出具體工具了。可根據本身的實際狀況,利用上方的 Shell 代碼嘗試解決。
iOS 與 Android 系統
手機系統上一樣難以作到 macOS 上的「一鍵修復」,推薦使用上文中 Windows 系統小節的在線網站解決。
èªå 類型亂碼
這種亂碼的造成過程基本類似,但其中涉及的編碼卻各有不一樣,錯綜複雜。考慮到國內電腦用戶遇到的狀況,多出現於從國內的政府、院校、企業等網站下載文件時,通常屬於同一種類型,即 GBK 編碼解碼錯誤。下面將針對此種類型給出解決方法。
首先,我以常常出現亂碼的知網文獻下載爲例,使用各系統及瀏覽器進行測試。結果以下:
- Win10 1803版本 中文系統 Edge 瀏覽器下載文獻的文件名爲亂碼,IE 瀏覽器下載文件名正常,Chrome 瀏覽器下載文件名爲亂碼。
- macOS 10.13.4 中文系統 Safari 與 Chrome 瀏覽器下載文件名均正常。英文系統中,兩種瀏覽器下載文件名均爲亂碼。
- Ubuntu 16.04 系統,環境變量
LC_ALL="en_US.UTF-8"
狀況下,Firefox 瀏覽器下載文件名爲亂碼。
須要說明的是:上述結果僅代表使用這些系統、語言、瀏覽器組合進行下載時的通常狀況,並不能代表該組合下載時徹底有或無亂碼。這是因爲亂碼的產生與否,是由系統、瀏覽器、網站三方共同決定的。
macOS 系統
這裏,我一樣是使用 Automator 編寫了一個文件服務,無需網絡,支持批量處理。下載「å 修復文件名亂碼.workflow.zip」,解壓後雙擊安裝。
服務安裝
而後,右鍵單擊須要處理的文件,選擇服務子菜單中的 å 修復文件名亂碼,稍等便可。若是沒有這個服務項,就重啓試試。
修復演示
用 Automator 打開會發現其原理很簡單,只有「運行 Shell 腳本」的操做,其中的 Shell 代碼爲:
for f in "$@" do fileName=$(basename ${f}) filePath=$(dirname ${f})
能夠看到上述代碼是在解決兩種亂碼狀況,其中 GBK 亂碼是咱們常遇到的,UTF-8 類型的則是由讀者在下方評論中提出的,較爲少見,順手加上。
Windows 系統
首先,下載 Python3.6,而後,「文件名亂碼修復.bat」,隨意放在你喜歡的位置。須要修復文件名亂碼時,拖動文件到 文件名亂碼修復.bat 上方後釋放便可,代碼以下:
python -c "import sys,os;fp=os.path.dirname(sys.argv[1]);fn=os.path.basename(sys.argv[1]);os.rename(sys.argv[1],os.path.join(fp,fn.encode('latin1').decode('gbk')))" %1
Win亂碼修復
Linux 系統
因爲 Linux 各發行版及桌面環境差別較大,這裏僅給出核心命令。
echo 文件名亂碼 | iconv -t latin1 | iconv -f gbk
經過運行該命令,可獲得正常的文件名稱,複製後重命名便可。
iOS 與 Android 系統
若是在 iOS、Android 上遇到相似於「èªå¨é£è±è½»ä¼¼æ¢¦」文件名亂碼,那麼最好在電腦上從新下載後再修復名稱。這是因爲移動系統上對文件的處理,不像電腦系統上那麼方便。並且也應該避免複製文件名稱中的亂碼文字,由於亂碼中每每存在不可見字符,在複製粘貼過程當中可能出現遺漏或錯誤。
另外,若是繁體中文、日語等語言文字的電腦用戶遇到相似的文件名亂碼問題,可將本文代碼中的gbk
改成相應語言的編碼名稱以嘗試解決,如繁體中文 BIG五、日文 JIS。
結語
亂碼的出現老是讓人煩心的。但願本文介紹的方法可以幫助你解決遇到的問題。
若是你想了解第一種亂碼相關的 URL 編碼,能夠看 這篇文章。
第二種亂碼相關的字符編碼知識,則推薦閱讀:
> 下載 少數派 iOS 客戶端、關注 少數派公衆號,讓智能設備更好用 ⚡️