5

我正在研究如何根据每个句子的长度对文件进行排序,我从这个答案中发现了这个片段

perl -ne 'push @a, $_ } { print sort { length $a <=> length $b } @a' input
                      ^ ^  

我对其进行了测试并且它有效,但我不知道它是如何工作的!据我所见,语法是错误的。它有一个开放的右括号和一个非封闭的右括号,我已经标记了。
我真的很难弄清楚如何在 bash 中运行这样的 perl 命令
有人可以解释一下这个片段吗?

4

3 回答 3

10

}{是阿比盖尔在 1997 年发现的所谓蝴蝶或爱斯基摩人的问候。

基本上它关闭了开关while强加的循环-n,接下来}{是while循环之后执行的块。

这就是 perl 解析这一行的方式,

perl -MO=Deparse -ne 'push @a, $_ } { print sort { length $a <=> length $b } @a' input

LINE: while (defined($_ = <ARGV>)) {
    push @a, $_;
}{ # <==here it is

    print((sort {length $a <=> length $b;} @a));
}

更常见的方法是使用END{}块而不是}{运算符:

perl -ne '
  push @a, $_ 
  END { 
    print sort { length $a <=> length $b } @a
  }
' input
于 2013-09-15T17:18:57.037 回答
5

SzG 的回答是正确的:该脚本有效,因为该-n开关导致 Perl将代码包装在以下循环中:

LINE: while (<>) { # code goes here
;}

在编译它之前。因此,您的示例代码变为:

LINE: while (<>) { push @a, $_ } { print sort { length $a <=> length $b } @a
;}

这是一个完全有效的 Perl 脚本。


无论如何,编写该脚本的一种不那么老套的方法是:

perl -ne 'push @a, $_; END { print sort { length $a <=> length $b } @a }' input

甚至只是:

perl -e 'print sort { length $a <=> length $b } <>' input
于 2013-09-15T17:15:53.887 回答
3

-e script您使用该选项运行在命令行上指定的 Perl 脚本。如果您还添加了该-n选项,Perl 将在脚本周围加上一个

while(<>) {
    your-script-here
}

逐行读取指定文件的标准输入的循环。

于 2013-09-15T17:12:47.950 回答