为什么以下oneliner跳过第一行?

时间:2014-08-19 08:50:48

标签: perl

以下是示例:

$cat test.tsv 
AAAATTTTCCCCGGGG    foo
GGGGCCCCTTTTAAAA    bar
$perl -wne 'while(<STDIN>){ print $_;}' <test.tsv
GGGGCCCCTTTTAAAA    bar

这应该像cat一样,而不是tail -n +2。这里发生了什么?什么是正确的方法?

3 个答案:

答案 0 :(得分:4)

因为-n开关隐式地将你的代码放在一个逐行遍历文件的循环中。从开关列表中删除'n',或者(甚至更好)从代码中删除循环,只保留打印命令。

nbokor@nbokor:~/tmp$ perl -wne 'print $_;' <test.csv
AAAATTTTCCCCGGGG    foo
GGGGCCCCTTTTAAAA    bar

答案 1 :(得分:3)

使用-n选项可以创建它(取自man perlrun):

        while (<STDIN>) {
          while(<STDIN>){ print $_;} #< your code
        }

这显示了两个while(<STDIN>)个实例。他们都接受了STDIN的所有可用输入,打破了换行符。

当你使用至少两行长的test.tsv运行时,while(<STDIN>)的第一个(外部)使用第一行,第二个(内部)使用第二行 - 所以你的print语句首先传递给第二行。

如果test.tsv中有两行以上,则内部循环将从第二行开始打印出所有行。

使这项工作正确的方法就是依靠传递给perl的-n选项:

perl -wne 'print $_;' < test.tsv

答案 2 :(得分:2)

删除-n命令行选项。它重复了while(<STDIN>){ ... }

$perl -MO=Deparse -wne 'while(<STDIN>){ print $_;}'
BEGIN { $^W = 1; }
LINE: while (defined($_ = <ARGV>)) {
    while (defined($_ = <STDIN>)) {
        print $_;
    }
}
-e syntax OK