我正在研究一个Perl程序,它包含以下用于处理输入文件的段。我不明白s/^\s+//;
的用途是什么?而且,什么是'|'和'||'代表open(FILE, "cat $fileName |") || die "could not open file";
open(FILE, "cat $fileName |") || die "could not open file";
while (<FILE>)
{
s/^\s+//;
my @line = split;
if ($line[0]!~ /\:/) {$mark=0}
my $var = $line[$mark];
## some other code
}
答案 0 :(得分:2)
您可以在perlfunc中阅读各种功能的文档。
此代码将打开一个文件以便通过cat
管道的相当谨慎的方式进行读取,而不是简单地打开文件。 |
表示shell命令cat
通过管道连接到open命令,我们的文件句柄将从输出中读取。
||
只是或。打开管道,如果失败,程序就会死掉。
while(<FILE>)
将读取输入的每一行,并将每行分配给$_
。然后在替换中隐含地使用该行并在下面拆分。即s/^\s+//
等于$_ =~ s/^\s+//
,split
等于split(' ', $_)
。
s/^\s+//
将删除前导空格。拆分将在空白上拆分每一行,元素存储在数组@line
中。
由于在空格上使用隐式拆分,因此不需要使用s/^\s+//
剥离前导空格,因为这是自动完成的。
如果第一个元素不包含冒号:
,则$mark
设置为0.否则,它不会被设置,并且可能会使用上一次迭代中的值,因为它不是在循环内定义。最后,$var
被初始化为元素编号$mark
,其为0或其他。
ETA:作为一个相当阴险的oops:如果$mark
未定义,即它不包含冒号,那么$var
仍将被分配$line[0]
,因为undef
将被警告转换为0
。如果use warnings
没有生效,则此错误是无声的,因此是阴险的。
此代码似乎是由对perl不太了解的人编写的,使用它可能不太安全。
答案 1 :(得分:2)
替换修剪出现在行首(whitespace)的前导^
,将任何非空白字符留作第一个。
open... || die ...
中的||
operator是一个高优先级或。如果open
失败,则die
会执行。
open(FILE, "cat $fileName |")
浪费了外部流程。要读取文件以进行输入,只需执行以下操作:
open FILE, '<', $filename or die qq{Could not open "$filename" for reading: $!};
open
调用的括号是可选的,因为or
没有紧密绑定。
使用词法文件句柄也更好:
open my $fh, '<' $filename or die qq{Could not open "$filename" for reading: $!};
此文件句柄分配给词法变量,该变量仅存在于声明的范围内。程序流退出此范围后,文件将自动关闭。
答案 2 :(得分:0)
部分原因是开发人员正在使用默认变量$_
。当你没有在函数中指定变量的名称时,许多Perl命令(我会说约1/3)命令$_
。例如,这些在语法上是相同的:
my $uppercase_name = uc($_);
my $uppercase_name = uc;
在这两种情况下,uc
函数将以大写字符打印$_
变量中的字符串。实际上,即使print
语句也使用$_
变量。同样,这些都是相同的:
print $_;
print;
在较新的Perl脚本中使用默认变量是不赞成的,因为它不会增加程序的清晰度,也不会使程序更快。我重写了您使用的相同代码段,以便显示丢失的$_
变量。它可能使代码更容易理解:
open(FILE, "cat $fileName |") || die "could not open file";
while ($_ = <FILE>)
{
$_ =~ s/^\s+//;
my @line = split $_;
if ($line[0] !~ /\:/) {
$mark = 0;
}
my $var = $line[$mark];
## some other code
}
请注意,while
语句将读取的行的值放入$_
变量,并且替换命令(s/^\s+//
)也是在$_
变量上运行。我希望能为你澄清一下代码。
现在提出您的问题:
_ [W]帽子做'|'和'||'代表什么?
||
表示或,就像执行这个或那个一样。实际上,或可以被认为是if语句:
if (not open(FILE, "cat $fileName |")) {
die "could not open file";
}
也就是说,如果open语句失败,则执行die
语句。如果open语句确实设法打开该文件,则不要执行die
语句。
在Perl中,您现在可以看到or
而不是||
,例如:
open(FILE, "cat $fileName |") or die "could not open file";
这使得含义更加明显:打开文件,或者杀死程序。
文件名末尾的单个管道(|
)表示在open语句(cat $filename
)中执行该命令,并从该命令的输出中读取。想象一下这样的事情:
open (COMMAND, "java -jar foo.war|") or die "Can't execute 'java -jar foo.war'";
现在,我正在运行命令java -jar foo.war
并在我的Perl脚本中使用其输出。
你也可以这样做:
open (MAIL, "|mail $recipient") or die "Can't mail $recipient";
print MAIL "Dear $recipient\n\n";
print MAIL "I hope everything is well.\n";
print MAIL "Sincerely,\n\nDavid";
close MAIL;
我现在打开命令mail $recipient
并使用print
语句写入它。在这种情况下,我正在通过简单的消息向$recipient
发送电子邮件。
我不明白什么是s / ^ \ s + //;用于?
在原始程序中,它本身就是一条线:
s/^\s+//;
我添加了缺少变量,这有助于澄清一点:
$_ =~ s/^\s+//;
这是Perl中的Substitute命令。它取$_
变量并用正则表达式^\s+
代替。如果你不理解什么是正则表达式,你应该看一下关于这个主题的Perldoc tutorial。基本上,这是从行的开头删除所有空格,制表符和其他形式的空格。