为什么在perl一行程序中以slurp模式使用-p |-n?

为什么在perl一行程序中以slurp模式使用-p |-n?,perl,Perl,在perl中,一行程序的slurp模式是0777,我希望它与下面的脚本相同 open my $fh, "<","file"; local $/; my $s = <$fh>; #now whole file stored into the $s 原因有二,;首先,在一行中完成工作。一行的全部思想是避免实际编写脚本文件。你的含糊不清的选择不能合理地用一行字来表达 其次,-n和-p允许对每行执行操作-这与简单地读取所有行不同。在使用slurpy选项读入行之后,可以使用map来处理

在perl中,一行程序的slurp模式是
0777
,我希望它与下面的脚本相同

open my $fh, "<","file";
local $/;
my $s = <$fh>; #now whole file stored into the $s

原因有二,;首先,在一行中完成工作。一行的全部思想是避免实际编写脚本文件。你的含糊不清的选择不能合理地用一行字来表达


其次,-n和-p允许对每行执行操作-这与简单地读取所有行不同。在使用slurpy选项读入行之后,可以使用map来处理每一行,但随后我们返回到多行代码,而不是命令行开关。

没有
-n
-p
没有隐式
while()
循环,因此不会设置默认的
$
,而且标准数据也没有被读取。如果我们想在slurp模式下默认设置
$\uu
,我们需要这些开关中的一个以及
-0777
,它本身仅(取消)设置
$/
。这个

echo "hello" | perl -0777 -e 'print'
不打印任何内容,并使用
-w
警告
使用未初始化值$\ucode>。现在这个

echo "hello" | perl -0777 -e '$v = <>; print $v'
可以一次读取所有内容,但没有默认的输入和模式搜索空间() 因此,读取的内容不会分配给任何内容。带着警告,我们可以听到它。(感谢您在评论中提到STDIN。)

与使用
-n
等效的代码为

while (defined($_ = <ARGV>)) { }
while(defined($)=列出了“…Perl将假定
$”\u
..”的条件。最后一个项目符号

readline
readdir
每个
操作的结果作为
while
测试的唯一标准进行测试时,放置下一个值或输入记录的默认位置。在
while
测试之外,不会发生这种情况

使用
-n
-p
开关,我们可以得到这个以及所有标准输入

注意,您的示例并不完全相同,因为它确实分配了


评论问题中的具体陈述


slurp不是通过这些开关“启用”的——它是通过
-0777
标志设置的。我们使用它们是因为我们获得了自动标准输入和
$

它更像是运行
perl-n0e'$s=$\ucode>:

% perl -MO=Deparse -n0e '$s = $_'
BEGIN { $/ = "\000"; $\ = undef; }                                                                                                                                                                                                
LINE: while (defined($_ = <ARGV>)) {                                                                                                                                                                                              
    $s = $_;                                                                                                                                                                                                                      
}                                                                                                                                                                                                                                 
-e syntax OK
上述内容将用文件1、文件2和文件3中的
b
替换所有
a
。删除:

BEGIN { $^I = ""; }                                                                                                                                                                                                               
LINE: while (defined($_ = <ARGV>)) {                                                                                                                                                                                              
    s/a/b/g;                                                                                                                                                                                                                      
}                                                                                                                                                                                                                                 
continue {                                                                                                                                                                                                                        
    die "-p destination: $!\n" unless print $_;                                                                                                                                                                                   
}                                                                                                                                                                                                                                 
-e syntax OK 
开始{$^I=”“;}
行:while(已定义($){
s/a/b/g;
}                                                                                                                                                                                                                                 
继续{
模具“-p目的地:$!\n”,除非打印$;
}                                                                                                                                                                                                                                 
-e语法正常

选项
-p
-n
会影响Perl是否自动循环和打印。这与Perl是因为slurp模式而循环一次还是因为它不在slurp模式而循环多次无关。@JonathanLeffler是的,但对于这两个选项中的任何一个,隐式
while()
导致实际设置了
$\ucode>,而没有它们则无法设置。因此,如果我们想在slurp模式下使用
$\ucode>,我们需要
-n
-p
(我在下面发布了更多信息。)@zdim:如果没有
-p
-n
选项,就不会有隐式循环,也不会自动读取命令行文件名或标准输入。你必须自己添加这些内容。@JonathanLeffler是的,这就是我的意思——我想OP是在问,我们为什么要将它们与slurp一起使用。有了这个循环,所以
$\code>确实设置好了,我们可以使用它。
% perl -MO=Deparse -n0e '$s = $_'
BEGIN { $/ = "\000"; $\ = undef; }                                                                                                                                                                                                
LINE: while (defined($_ = <ARGV>)) {                                                                                                                                                                                              
    $s = $_;                                                                                                                                                                                                                      
}                                                                                                                                                                                                                                 
-e syntax OK
perl -i -pe 's/a/b/g' file1 file2 file3
BEGIN { $^I = ""; }                                                                                                                                                                                                               
LINE: while (defined($_ = <ARGV>)) {                                                                                                                                                                                              
    s/a/b/g;                                                                                                                                                                                                                      
}                                                                                                                                                                                                                                 
continue {                                                                                                                                                                                                                        
    die "-p destination: $!\n" unless print $_;                                                                                                                                                                                   
}                                                                                                                                                                                                                                 
-e syntax OK