使用以下脚本时为什么输出不同?

时间:2016-06-30 05:20:29

标签: perl

我的输入文件:

103M:A|PDBID|CHAIN|SEQUENCE
MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMKASEDLKKAGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG

SCRIPT1:

open(FH,"103m.txt")||die "error";
while(<FH>)
{
    print <FH>;
}

SCRIPT2:

open(FH,"103m.txt")||die "error";
while(<FH>)
{
    print $_;
}

我的script1输出:

MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMKASEDLKKAGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQ

Script2输出:

103M:A|PDBID|CHAIN|SEQUENCE
MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMKASEDLKKAGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG

1 个答案:

答案 0 :(得分:2)

这实际上是一个有趣的问题,因为有两种不同的perl概念在起作用。

第一个是 - <FH>导致从文件中读取一行。

所以如果你:

while ( <FH> ) {

实际获得的是:

while ( defined $_ = <FH> ) { 

}

正在从文件句柄中读取一行,放入$_,然后测试它是否已“定义”(例如读取正常) - 如果不是,则退出循环。

因为在第一个示例中 - 您不打印$_ - 该行被有效地丢弃。

第二个在游戏中认为是关于背景的。

如果您这样做,

<FH>的工作方式会有所不同:

my $line = <FH>;

my @lines = <FH>; 

在前一种情况下 - 读取一行(直到下一个$/ - 默认为\n)。在后者中,将读取整个文件,每个数组元素一个“行”。

现在,这很重要,因为while循环读取 - 在标量上下文中(一次一行)。但print <FH>是列表上下文 - 并将导致整个文件被读取(和打印)。

所以在你的第一个例子中 - 你正在迭代循环一次。丢弃第一行,并打印其他所有内容。

在第二个循环中 - 你每行迭代一次,然后打印每一行。

2行文件的差异并不明显,但是:

#!/usr/bin/env perl
use strict;
use warnings;

my $count; 

while ( <DATA> ) {
   print "Loop count ", ++$count,"\n";
   print '$_ is "', $_,"\"\n";
   print "Printing <DATA>\n";
   print <DATA>;
}

__DATA__
line 1 
line 2
line 3
line 4
line 5

这将输出:

Loop count 1
$_ is "line 1 
"
Printing <DATA>
line 2
line 3
line 4
line 5

但是采取你的第二个例子:

#!/usr/bin/env perl
use strict;
use warnings;

my $count; 

while ( <DATA> ) {
   print "Loop count ", ++$count,"\n";
   print '$_ is "', $_,"\"\n";
   print 'printing $_',"\n";
   print $_;
}

__DATA__
line 1 
line 2
line 3
line 4
line 5

给出了:

Loop count 1
$_ is "line 1 
"
printing $_
line 1 
Loop count 2
$_ is "line 2
"
printing $_
line 2
Loop count 3
$_ is "line 3
"
printing $_
line 3
Loop count 4
$_ is "line 4
"
printing $_
line 4
Loop count 5
$_ is "line 5"
printing $_
line 5

注意 - 上面没有chomp,因此$_包含换行符。

虽然我们正处于这种状态 - open的这种形式并不是一种好的做法。我建议改为:

open ( my $input, '<', "103m.txt" ) or die $!;