在perl中,一个衬里啜食模式是open my $fh, "<","file";
local $/;
my $s = <$fh>; #now whole file stored into the $s
我希望哪个等于下面的脚本
-p|-n
这里我们没有使用任何循环将所有元素存储在一起(单个数据)。
但是在perl one liner中,为什么我们使用-0777
开关来启用slurp模式(-p | -n
)?这里的性能提升是多少?
open my $fh, "<","file";
my $s;
while (<$fh>)
{
$s.=$_;
}
print $s;
用于循环目的。那么一个班轮的实际表现就像下面的剧本或其他什么?
EditText
答案 0 :(得分:5)
如果没有-n
或-p
,则没有隐式while (<>)
循环,因此默认$_
未设置,并且STDIN也未读取。如果我们希望在slurp模式下默认<>
和$_
,我们需要其中一个开关以及-0777
,它本身只是(联合国)设置$/
。此
echo "hello" | perl -0777 -e 'print'
不打印任何内容,-w
警告Use of uninitialized value $_
。现在这个
echo "hello" | perl -0777 -e '$v = <>; print $v'
会打印hello
。 STDIN
可以读入一个变量,因此&#39; slurp&#39; 是。
就这相当于什么而言,仅仅-0777
只有$/ = undef
。如果我们添加一个读取
# use warnings;
local $/;
<>;
print;
<>
一次性读取所有内容,但没有默认输入和模式搜索空间 $_
,因此读取的内容不会分配给任何内容。随着警告我们得到了解。 (感谢Jonathan Leffler在评论中提到STDIN。)相当于使用-n
的代码是
while (defined($_ = <ARGV>)) { }
因此我们获得标准输入并设置$_
。运行perl -MO=Deparse -n -e 1
即可查看这些内容。
在perlvar中列出的条件为&#34; ... Perl将假设$_
... &#34;。最后一颗子弹
当
<FH>
,readline
,readdir
或each
操作的结果自行测试时,放置下一个值或输入记录的默认位置while
测试的唯一标准。在while
测试之外,这不会发生。
使用-n
或-p
开关,我们可以获得此标准输入。
注意,您的示例并非完全等效,因为它 分配。
评论问题中的具体陈述。
啜食没有&#34; 启用&#34;通过这些开关 - 它由-0777
标志设置。我们使用它们是因为我们获得了自动标准输入和$_
。
答案 1 :(得分:2)
这更像是运行perl -n0e '$s = $_'
:
% perl -MO=Deparse -n0e '$s = $_'
BEGIN { $/ = "\000"; $\ = undef; }
LINE: while (defined($_ = <ARGV>)) {
$s = $_;
}
-e syntax OK
正如您所看到的那样,唯一的“开销”是一次性检查。毕竟$/
是一个NUL字节。正如其他人所指出的,这是完成工作的一种简单方法:
考虑这个简单的sed等于:
perl -i -pe 's/a/b/g' file1 file2 file3
以上内容将替换file1,file2&amp;中a
的所有b
。文件3。 Deparsed:
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/a/b/g;
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
答案 2 :(得分:1)
有两个原因;首先,要在一行中完成的工作。单行的整个想法是避免实际编写脚本文件。你的邋alternative替代品不能合理地表达出来。
其次,-n和-p允许对每一行采取行动 - 这与简单地读取所有行不同。使用你的单一替代品读取行后,可以使用map来处理每一行 - 但是我们回到多行代码而不是命令行开关。