2014年3月20日 星期四

Linux 顯示/編輯 16 進位 HEX MODE

http://linux.vbird.org/linux_basic/0220filemanager/0220filemanager-fc4.php

非純文字檔: 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
.....中間省略.......
利用這個指令,可以將 data file 或者是 binary file 的內容資料給他讀出來喔! 雖然讀出的來數值預設是使用非文字檔,亦即是 16 進位的數值來顯示的, 不過,我們還是可以透過 -t c 的參數來將資料內的字元以 ASCII 類型的字元來顯示, 雖然對於一般使用者來說,這個指令的用處可能不大,但是對於工程師來說, 這個指令可以將 binary file 的內容作一個大致的輸出,他們可以看得出東西的啦~ ^_^


 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
$

 
再來是DOS的檔案,從紅色部分的標示可以看出來檔案結尾是十六進位的0x0d 0x0a:
$ 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.txt


http://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 接著再存檔囉

沒有留言:

張貼留言