DOS,UNIX中的回車換行區別
這幾天寫了個多執行緒的資料抽取perl指令碼,速度很快,可達到1G/m以上。可是今天做fastload載入時,被破了瓢冷水:
抽過來的所有的檔案都無法正常的載入,表現的形式是我抽取的資料始終要比BOSS送過來的資料大那麼一點點,但記錄
條數沒有異常。於是我開始了艱難的查錯之旅:
2.用cygwin檢視各條記錄的長度,輸出長度不對的行:
awk '{ if ( length($0) !=行位元組數) {print $0;print NR} }' xxx.dat
結果令我失望,所有行的長度均正常;
3.編寫一perl指令碼,比較我抽取的資料檔案和正確檔案的差異:
#!/user/bin/perl
use strict;
use File::Basename;
use POSIX qw(strftime);
open(IN, "E:ETLDATAprocessQ01_CUST_PERSON_INFO_T_20090203.dat") or die "open error: $!";
my @x =
close (IN);
open(IN, "E:ETLDATAprocessQ01_CUST_PERSON_INFO_T_20090203_1.dat") or die "open error: $!";
my @y =
close (IN);
chomp(@y);
my $p = join('|', map{quotemeta} @y);
#print (grep /$p/, @x);
print (grep ! /$p/, @x);
五分鐘後,執行完畢,結果令人沮喪,輸出日誌大小為0;
4.我開始懷疑是不可見字元引起的異常,可是這個怎麼查呢?
5.新的一天開始了,有高手過來,機會難得,開問。高手就是高手,聽了我的描述,他決定用UE檢視檔案的十六進位制編碼,
用UE開啟,彈出視窗:"轉換成DOS模式",點“是”,比較兩檔案的十六進位制編碼,發現完全一樣!
怎麼辦呢?先看看大小差異有沒有什麼規律:
一行資料可見字元的長度為388*25538=9908744
正常:9934282 = 9908744 + 25538
異常:9959820 = 9934282 + 25538
也就是說正常情況下不可見字元數為每行1個,而我抽取的為每行2個
再用UE開啟,彈出視窗:"轉換成DOS模式",點“是”,比較兩檔案的十六進位制編碼,重點關注不可見的回車換行符,發現還是完全一樣!怎麼回事呢?突然想起BOSS的資料庫環境為UNIX,是不是編碼不一樣呢?找到UE選單中“DOS到UNIX”轉換,轉換格式,儲存。發現大小變為正確值,fastload,成功。突然明白,檢視十六進位制編碼完全一樣的罪魁禍首在於慣性的點選UE彈出的"轉換成DOS模式"。驗證一下,點選彈出視窗的“否”,果然發現區別,抽取資料的回車換行的編碼為“0A0D”,正確資料為“0D”。
結論:dos與unix在檔案中換行字元的表現機置存在差異:
dos格式下,切換一行是二個字元的,由回車(od),換行(oa),檔案尾部直接EOF(檔案結束標誌)
而unix下,切換一行,使用的是單換行符(oa),檔案最後一行也會增加該字元,然後才是eof
驗證如下:
windos下建一個檔案,1.txt,輸入:
afew
aef(到此打住)
使用ultraedit的十六進位制檢視,或者上傳到unix機,使用:"xxd 檔名"以十六進位制檢視檔案,結果如下:
0000000: 6166 6577 0d0a 6165 66 afew..aef
增加了Od,Oa二個字元
而在unix下,簡單建立一個同樣的檔案:"vi 2.txt",輸入
afew
aef(同樣到此打住)
使用"xxd 2.txt" 檢視:
0000000: 6166 6577 0a61 6566 0a afew.aef.
可以看到,第一行後邊只有一個"oa" 換行符,同時最後一行也自動增加了oa字元
現在用wc檢視下二個檔案的情況:
>wc -l 1.txt 2.txt
1 2 9 1.txt
2 2 9 2.txt
3 4 18 total
可以看到,二個檔案的字元數是一樣的,這個上邊已經分析.
使用UE轉化工具dos2unix,功用是把dos的二個切換符轉化成unix的單個字元
>dos2unix 1.txt
>wc 1.txt
1 2 8 1.txt
>xxd 1.txt
0000000: 6166 6577 0a61 6566 afew.aef
發現回車符已經被去掉了.,
同樣使用轉化工具unix2dos,功用是把unix下的單換行字元轉化為dos下的二個字元:
>unix2dos 2.txt
>wc 2.txt
2 2 11 2.txt
>xxd 2.txt
0000000: 6166 6577 0d0a 6165 660d 0a afew..aef..
可以看到,二個單換行符已經轉化成dos下的四個字元,檔案大小也多了2個字元.
現在繼續使用wc檢視下這二個檔案情況:
>wc 1.txt 2.txxt
1 2 8 1.txt
2 2 11 2.txt
3 4 19 total
現在檔案的大小問題 ,已經換行符文題已經解決了,再來關注一下unix下一些工具所受到的影響 ,仔細看可以發現一個問題 :不管是什麼格式的,在windows下生成的和在dos下生成的,行數都差一,dos下建立的檔案最後一行哪裡去了?沒有統計到嗎?
是的,的確沒統計到,wc根據行未的oa字元判斷的行數,所以結果是最後一行被忽略了.而dos2unix僅是對已有的0a/0d到oa之前的轉化,對於windows下建立的檔案進行dos2unix,也不會在最後一行裡增加oa字元,所以即使用dos2unix後,檔案wc結果也會少一行
同樣受到影響的還有while語句
>while read line; do echo $line; done <1.txt
afew
可以看到,結果也只打出了一行,
sed就不受這個的影響了:
>sed 's/a/ccc/g' 1.txt
cccfew
cccef
再試awk命令:
>awk '{print $0}' 1.txt
afew
aef
也沒有受到影響
目前常用到的shell命令,就是wc/while語句,受到影響.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16723161/viewspace-1016821/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 終於搞懂了回車與換行的區別
- 【換行符】Windows、Unix、Mac不同作業系統的回車符 和換行符 WindowsMac作業系統
- 回車和換行
- oracle 回車、換行符Oracle
- Linux - 回車符和換行符及其在不同系統上的區別Linux
- C語言中回車,換行,空字元與空格:fgets和gets在讀取換行符的區別C語言字元
- js 去掉空格.回車.換行JS
- Android 回車換行的持久化Android持久化
- vi 中將 Windows 文字檔案中的 ^M (回車換行)全部替換掉Windows
- DOS命令的換行
- Windows & Unix 檔案格式之迷, 空格、回車換行、tab 轉換及其相關工具(轉載)Windows
- oracle中去掉文字中的換行符、回車符、製表符Oracle
- 替換SQL欄位中的換行符,回車符,空格等特殊符號SQL符號
- dos2unix, unix2dos 對應的命令(轉)
- js將文字框的內容回車換行符轉換為<br/>換行JS
- 我使用過的Linux命令之dos2unix - 將DOS格式文字檔案轉換成UNIX格式Linux
- 去掉檔案中LF(dos->unix)
- oracle中去掉文字中的換行符、回車符、製表符小結Oracle
- DOS/Windows和Linux/Unix間檔案格式轉換WindowsLinux
- ultraedit中將某字元替換為回車符字元
- dos2unix命令
- 關於在textarea中輸入回車換行和空格字元的正常顯示 (轉)字元
- 如何在 Unix 和 DOS 格式之間轉換文字檔案
- oracle去掉資料裡的tab、回車、換行等特殊符號Oracle符號
- 在Linux中,BASH 和 DOS之間的區別是什麼?Linux
- ACM中回車的問題ACM
- Linux和DOS的FORMAT命令區別(轉)LinuxORM
- 換行與回車(\r \n)的起源以及在編制語言中的使用
- 用查詢替換快速批次刪除Word中的回車符號符號
- 批次查詢替換excel單元格中的軟回車(alt + enter)Excel
- 菜鳥教程之工具使用(八)——EGit禁止自動轉換回車換行符Git
- 關於html編輯器的回車換行問題解決方案 (轉)HTML
- VSCode回車換行後自動調整程式碼格式VSCode
- 文字轉化工具dos2unix
- C++ 中四種強制型別轉換的區別C++型別
- 塊元素和行內元素的區別與轉換
- 認識Linux與Unix區別Linux
- unix系統當中 軟連線與硬連線的區別(轉)