非純文字檔: od
我們上面提到的,都是在查閱純文字檔 (ASCII 格式的檔案) 的內容。 那麼萬一我們想要查閱非文字檔,舉例來說,例如 /usr/bin/passwd 這個執行檔的內容時, 又該如何去讀出資訊呢?事實上,由於執行檔通常是 binary file ,使用上頭提到的指令來讀取他的內容時, 確實會產生類似亂碼的資料啊!那怎麼辦?沒關係,我們可以利用 od 這個指令來讀取喔!
[root@linux ~]# od [-t TYPE] 檔案 參數: -t :後面可以接各種『類型 (TYPE)』的輸出,例如: a :利用預設的字元來輸出; c :使用 ASCII 字元來輸出 d[size] :利用十進位(decimal)來輸出資料,每個整數佔用 size bytes ; f[size] :利用浮點數值(floating)來輸出資料,每個數佔用 size bytes ; o[size] :利用八進位(octal)來輸出資料,每個整數佔用 size bytes ; x[size] :利用十六進位(hexadecimal)來輸出資料,每個整數佔用 size bytes ; 範例: [root@linux ~]# od -t c /usr/bin/passwd 0000000 177 E L F 001 001 001 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000020 002 \0 003 \0 001 \0 \0 \0 260 225 004 \b 4 \0 \0 \0 0000040 020 E \0 \0 \0 \0 \0 \0 4 \0 \0 \a \0 ( \0 0000060 035 \0 034 \0 006 \0 \0 \0 4 \0 \0 \0 4 200 004 \b 0000100 4 200 004 \b 340 \0 \0 \0 340 \0 \0 \0 005 \0 \0 \0 .....中間省略....... |
http://dragonspring.pixnet.net/blog/post/33146613-%5Blinux%5D%5Btips%5D%E5%8E%BB%E9%99%A4dos%E6%AA%94%E6%A1%88%E8%A1%8C%E5%B0%BE%E7%9A%84%5Em
如果你在Linux環境底下用vi開啟DOS/Windows檔案的話,很有可能你在每行的結尾會看到一個『^M』的符號。若只是一般文字檔的話, 只會造成閱讀的困擾,倒還沒有其他問題。但是如果是shell script 的話,這可會造成執行錯誤。對於第一次遇到這個問題的人,恐怕是一頭霧水。
為了瞭解這個問題,首先我們來看看Linux的每行結尾和DOS/Windows有什麼不一樣。我們做了兩個檔案:Linux 格式的linux_file和DOS格式的dos_file,分別用hexdump來看看檔案結尾。
首先是Linux的檔案,從紅色部分的標示可以看出來檔案結尾是十六進位的0x0a:
$ hexdump -C linux_file 00000000 4c 69 6e 75 78 2d 66 6f 72 6d 61 74 20 66 69 6c |Linux-format fil| 00000010 65 2e 0a 45 6e 64 65 64 20 77 69 74 68 20 30 61 |e..Ended with 0a| 00000020 2e 0a |..| 00000022 $ |
$ hexdump -C dos_file 00000000 44 4f 53 2d 66 6f 72 6d 61 74 20 66 69 6c 65 2e |DOS-format file.| 00000010 0d 0a 45 6e 64 65 64 20 77 69 74 68 20 30 64 20 |..Ended with 0d | 00000020 30 61 2e 0d 0a |0a...| 00000025 $ |
因為DOS的檔案格式比Linux的格式多了個0x0d,所以會在vi裡面多了一個^M的符號(M是第13個字母,而0x0d就是十進位的13).
0x0d 和 0x0a 這兩個十六進位值除了用控制字元來表示以外,通常也用跳脫字元(Escape character)的 \n 和 \r 來表示。 整理之後,可以得到以下這個表格:
行尾(end of line) 表示法 | ||||
檔案格式 |
十六進位 |
控制字元 (Control character) |
跳脫字元 (Escape character) |
ASCII 名稱 |
Linux |
0x0a |
^J |
\n |
LF |
DOS/Windows |
0x0d 0x0a |
^M ^J |
\r \n |
CR LF |
知道了Linux與DOS檔案格式的差別之後,要處理這個問題也就呼之欲出了。在Linux的shell 命令裡,有兩個簡單的方法可以消除這個^M。
第一種方法,是利用sed的替換命令,將\r換成空字元:
sed "s/\r//" dos_file > dos_file_linux |
第二種方法,是利用tr的刪除命令,將\r刪除:
tr -d "\r" < dos_file > dos_file_linux |
任何一種方法做完之後,DOS的行尾已經轉換成Linux行尾:
$ hexdump -C dos_file_linux 00000000 44 4f 53 2d 66 6f 72 6d 61 74 20 66 69 6c 65 2e |DOS-format file.| 00000010 0a 45 6e 64 65 64 20 77 69 74 68 20 30 64 20 30 |.Ended with 0d 0| 00000020 61 2e 0a |a..| 00000023 $ |
(2012/10/16 Update) 在某些系統上可能會有dos2unix這個方便的小程式,以下的例子把 DOS 格式的 a.txt轉換成Linux格式的b.txt
dos2unix a.txt b.txthttp://changyy.pixnet.net/blog/post/25633298-%E4%BD%BF%E7%94%A8-vim-%E9%80%B2%E8%A1%8C-hex-mode-%E7%B7%A8%E8%BC%AF-%2816%E9%80%B2%E4%BD%8D%E7%B7%A8%E8%BC%AF%29
想說以前都用 UltraEdit 編輯遊戲存檔,沒想到 VIM 也能這樣做。
只要編輯時,下 :%! xxd ,就會以 Hex Mode 顯示檔案,然後編輯完想返回可以再用 :%! xxd -r 接著再存檔囉
沒有留言:
張貼留言