我已经开始玩perl了,我试图弄清楚如果我还提供循环,告诉perl
使用循环有什么问题?
看起来perl与相同的打开文件描述符混淆了,但我不知道为什么它会吃掉第一行?
perl -ne 'while (<>) { print $_; }'
当然在这个简单的例子中,我可以简单地perl -ne '{print $_}'
来达到相同的功能逻辑。
但我想知道的是,如果另一个while (<>) { }
被包裹,第一行消失的双循环会出现什么问题?
$ perl -ne '{print $_}' hello
hello
hello
world
world
^C
$ perl -ne 'while (<>) { print $_; }'
hello
world
world
^C
更新:根据答案,似乎正在发生的事情是Perl正在等待STDIN输入的第一个循环。在STDIN上接收输入后,输入被分配给内部缓冲区$_
,逻辑进入第二个循环,再次等待新的STDIN输入。收到新的STDIN输入后,它会使用新的STDIN输入破坏STDIN缓冲区$_
并开始打印。
答案 0 :(得分:9)
您可以使用O=Deparse
检查单行生成的代码。
<强>首先强>
$ perl -MO=Deparse -ne 'print $_;' file
LINE: while (defined($_ = <ARGV>)) {
print $_;
}
-e syntax OK
<强>第二强>
$ perl -MO=Deparse -ne 'while (<>) { print $_; }' file
LINE: while (defined($_ = <ARGV>)) {
while (defined($_ = <ARGV>)) {
print $_;
}
}
-e syntax OK
现在,很容易知道第二种情况有什么问题。外面吃了第一行文件而丢失了。
答案 1 :(得分:3)
-n
标志将您的代码包装在while (<>) { ... }
构造中。
所以在你的第二个例子中,实际执行的代码是
while (<>) # reads a line from STDIN, places it in $_
{
# you don't do anything with the contents of $_ here
while (<>) # reads a line from STDIN, places it in $_, overwriting the previous value
{
print $_; # prints the contents of $_
}
}
这意味着第一个<>
读取的行只是丢失了。