DOS,UNIX中的回车换行区别

这几天写了个多线程的数据抽取perl脚本,速度很快,可达到1G/m以上。可是今天做fastload加载时,被破了瓢冷水:
抽过来的所有的文件都无法正常的加载,表现的形式是我抽取的数据始终要比BOSS送过来的数据大那么一点点,但记录
条数没有异常。于是我开始了艰难的查错之旅:

[@more@]1.用UE查看数据文件,无明显异常:
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/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/16723161/viewspace-1016821/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值