Shell亂碼文件中的控制字符處理
author:潤明2012-2-17QQ:226399587http://blog.csdn.net/runming918
一、顯示文件中的控制字符
當從其他系統下載文件時,有時要刪除整個文件的控制字符(非打印字符),從菜單中捕獲一個應用的屏幕輸出有時也會將控制字符輸出進文件,怎樣知道文件中是否有控制字符?使用cat-vfilename命令,屏幕會亂叫,且到處都是一些垃圾字符,這可以確知文件中包含有控制字符,如果有興趣可以觀察一下這些字符以便於更加確認它們是控制字符。一些系統中使用catfilename而不是cat-v來查看非打印字符。
sed格式爲:[address,[address]]l ‘l’意爲列表。
一般情況下要列出整個文件,而不是模式匹配行,因此使用l要從第一到最後一行。模式範圍1,$即爲此意。
如果cat一個文件,發現實際上包含有控制字符。
$ cat -v a.txt This is the F1 key:^[OP This is the F2 key:^[OQ |
現在運行sed命令,觀察輸出結果。
$ sed -n '1,$l' a.txt This is the F1 key:\033OP$ This is the F2 key:\033OQ$ $ |
sed找到並顯示了兩個控制字符。\033代表退格鍵,OP爲F1鍵值,放在退格鍵後。第二行也是如此。各系統控制字符鍵值可能不同,主要取決於其映射方式(例如使用terminfo或termcap)。
如果要在文本文件中插入控制字符F1鍵,使用vi查看其鍵值,操作如下:
•啓動vi。
•進入插入模式。
•按下<Ctrl>鍵,然後按<v>鍵(出現a^)。
•釋放上述兩個鍵。
•按下F1鍵(顯示[OP]。
•按下<ESC>鍵(顯示F1鍵值)。
二、處理控制字符
處理這樣的控制字符有幾種辦法(但不一定滿足所有情況,具體情況具體實現吧)。
方法一:直接執行 dos2unix a.txt (這只可以處理dos到unix下的換行問題)
方法二:使用sed剔除控制字符。
下面是傳送過來的文件(dos.txt)的部分腳本。必須去除所有可疑字符,以便於帳號所有者使用文件。
$ cat -v dos.txt 12332##DISO##45.12^M 00332##LPSO##23.14^M 01299##USPD##34.16^M |
可採取以下動作:
1)用一個空格替換所有的(##)符號。
2)刪除起始域中最前面的0(00)。
3)刪除行尾控制字符(^M)。
一些系統中,回車符爲^@和^L,如果遇到一些怪異的字符,不必擔心,只要是在行尾並且全都相同就可以。按步執行每一項任務,以保證在進行到下一任務前得到理想結果。使用輸入文件dos.txt。
任務1。刪除所有的#字符很容易,可以使用全局替換命令。這裏用一個空格替換兩個或更多的#符號。
$ sed 's/##*/ /g' dos.txt | cat -v 12332 DISO 45.12^M 00332 LPSO 23.14^M 01299 USPD 34.16^M |
任務2。刪除所有行首的0。使用^符號表示模式從行首開始,^0*表示行首任意個0。模式s/^0*//g設置替換部分爲空,即爲刪除模式,正是要求所在。
$ sed 's/^0*/ /g' dos.txt | cat -v 12332##DISO##45.12^M 332##LPSO##23.14^M 1299##USPD##34.16^M |
任務3。最後去除行尾^M符號,爲此需做全局替換。設置替換部分爲空。模式爲:‘s/^m//g’,注意‘^M’,這是一個控制字符。要產生控制字符(^M),需遵從前面產生F1鍵同樣的處理過程。步驟如下;鍵入seds/,然後按住<Ctrl>鍵和v鍵,釋放v鍵,按<return>鍵。下面命令去除行尾^M字符。
$ sed 's/^M//g' dos.txt | cat -v 12332##DISO##45.12 00332##LPSO##23.14 01299##USPD##34.16 |
分步測試預想功能對理解整個過程很有幫助。用sed在移到下一步前測試本步功能及結果很重要。如果不這樣,可能會有一大堆包含怪異字符的意料外的結果。
方法三:使用sed剔除控制字符。
tr的第一個功能就是轉換控制字符,特別是從dos向UNIX下載文件時,忘記設置ftp關於回
車換行轉換的選項時更是如此。
下面是故意沒有設置轉換開關的一個文本文件,是關於文具需求的一部分內容。使用cat -v顯示控制字符。
$ cat -v dos.txt 12332^^##DISO##45.12^M 00332^^##LPSO##23.14^M 01299^^##USPD##34.16^M |
猜想^^^^^^是tab鍵。每一行以Ctrl -M結尾,文件結尾Ctrl -Z,以下是改動方法。
使用man ascii命令,查看ASCII表。^的八進制代碼是136,^M是015,tab鍵是011,^Z是032 ,下面將按步驟完成最終功能。
$ tr -s "[^^]" "[\011*]" < dos.txt | tr -s "[\015]" "[\012*]" | tr -s "[##]" " " | cat -v 12332 DISO 45.12 00332 LPSO 23.14 01299 USPD 34.16 |