Chinaunix

标题: 求助,perl读取文件的问题 [打印本页]

作者: telecomshy    时间: 2011-03-21 16:39
标题: 求助,perl读取文件的问题
本帖最后由 telecomshy 于 2011-08-16 17:12 编辑

读取一个文件:
  1. #!/usr/bin/perl -w
  2. open(FH,"1111.txt");
  3. while($line=<FH>){
  4.         print $line;
  5. }
复制代码
这样写,或者直接:
  1. #!/usr/bin/perl -w
  2. open(FH,"1111.txt");
  3. while(<FH>){
  4.         print <FH>;
  5. }
复制代码
都没问题,但是稍微改动一下:
  1. #!/usr/bin/perl -w
  2. open(FH,"1111.txt");
  3. while(<FH>){
  4.                $line=<FH>
  5.         print $line;
  6. }
复制代码
读取出来的文件就会有丢失的情况。这是什么原因呢?这2种写法有什么区别吗?
后面一种写法也时准时不准的,跟1111.txt源文件好像还有关系。

======================================================
多日以后再来总结:
第一种不用多说,第二种print,就像版主所说,直接print FH,则是进行了一次foreach循环,将剩下的全部输出了。第三种则是将一行赋值给$line,因为此时$/默认为换行符,此时如果加一行代码.
  1. #!/usr/bin/perl -w
  2. open(FH,"1111.txt");
  3. while(<FH>){
  4.                local $/;
  5.                $line=<FH>
  6.         print $line;
  7. }
复制代码
则会和第二种一样,剩下的全部输出了。
作者: ziyunfei    时间: 2011-03-21 17:07
第二第三都不对。
作者: 珞水的大叔    时间: 2011-03-21 17:11
本帖最后由 珞水的大叔 于 2011-08-01 12:00 编辑

while(<FH>)会读一行文件,存放在$_里
print <FH>又会读一行文件,直接显示在屏幕上
$line=<FH>也会读一行文件,存放在$line里
这样说明白么,呵呵

上次说错了,print <FH>应该不是读一行,而是读所有……
不好意思啊
修改于2011年8月1日
作者: telecomshy    时间: 2011-03-21 17:16
本帖最后由 telecomshy 于 2011-03-21 17:25 编辑

刚测试了一下。假设1111.txt内容为
1
2
3
4
5
6
用第一种方法,全部正确读取。
第三种方法,读取为
2
4
6
可以理解。
用第二种方法,读取为
2
3
4
5
6
果然如此,了解了。第三种真是有意思。我理解是while(<FH>)以后,等print的时候,已经是第二行,而print以后却不会换行,下次while从第二行读取,所以总是第一行没有。不知道是否正确。

我的天呀,合着我弄的几个小东西起码少读取了一半的内容。
作者: liuqiao007    时间: 2011-03-25 09:22
把<FH>存数组里
作者: masylichu    时间: 2011-03-25 09:34
区别很大啊,$name=<>和@name=<> ,前者是读一行,后者是读全部。
作者: 超级细菌    时间: 2011-03-25 09:48
这确实有点意思,我也经常遇到,但是我还是有点不明白,既然没有用chomp的话,为什么会就忽略了呢?楼主,你明白了的话,能再详细说一下各自的运行过程吗?谢了
作者: telecomshy    时间: 2011-05-28 10:39
while()会读一行文件,存放在$_里
print 又会读一行文件,直接显示在屏幕上
$line=也会读一行文件,存放在 ...
珞水的大叔 发表于 2011-03-21 17:11


时隔多日再来看,发现开始理解的还是有点偏差。print <FH>不是读一行了,而是把剩下的全部都输出了。
一行print <FH>,就相当于while(<FH>){print ;}
作者: telecomshy    时间: 2011-05-28 10:45
这确实有点意思,我也经常遇到,但是我还是有点不明白,既然没有用chomp的话,为什么会就忽略了呢?楼主,你 ...
超级细菌 发表于 2011-03-25 09:48


第一种方法就是一行一行读取,这个好理解;
第二种方法while的时候拿出一行赋给$_,print <FH>把剩下的全部一次性输出到屏幕,所以输出的结果没有第二行;
第三种方法while的时候拿出一行,$line=<FH>又拿出一行,所以输出的结果总是$line定义的那一行;

错误还是由于对文件句柄理解不深刻啊。
作者: flw    时间: 2011-05-28 11:42
时隔多日再来看,发现开始理解的还是有点偏差。print 不是读一行了,而是把剩下的全部都输出了。
一行 ...
telecomshy 发表于 2011-05-28 10:39

理解的还是不对。
print <FH> 不是等于 while(<FH>){ print },而是等于 foreach (<FH>){ print },也就是 @lines = <FH>; print @lines;
作者: yybmsrs    时间: 2011-05-28 11:46
实际上还是context的原因
作者: telecomshy    时间: 2011-05-28 15:00
理解的还是不对。
print  不是等于 while(){ print },而是等于 foreach (){ print },也就是 @lines =  ...
flw 发表于 2011-05-28 11:42


恩,while是一行一行读取,forearch是一次性读入。
作者: huazai202_cu    时间: 2012-05-07 10:22
正在学习中,perl比shell难啊
作者: flw    时间: 2012-05-07 11:00
huazai202_cu 发表于 2012-05-07 10:22
正在学习中,perl比shell难啊

shell 是平面,Perl 是球面。
shell 简单但是无限。Perl 复杂但是可被精通。
作者: hayida    时间: 2012-05-07 15:59
有点意思!!
作者: wonderall01    时间: 2012-05-08 19:37
回复 1# telecomshy
第二种情况也少读一行,不过不同的是第二个一次读取全部文件,而第三个读取是一行一行读取的。
   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2