我编写了一个perl脚本来计算文件中字符的出现次数。 到目前为止,这就是我所拥有的,
#!/usr/bin/perl -w
use warnings;
no warnings ('uninitialized', 'substr');
my $lines_ref;
my @lines;
my $count;
sub countModule()
{
my $file = "/test";
open my $fh, "<",$file or die "could not open $file: $!";
my @contents = $fh;
my @filtered = grep (/\// ,@contents);
return \@filtered;
}
@lines = countModule();
#@lines = $lines_ref;
$count = @lines;
print "###########\n $count \n###########\n";
我的测试文件如下所示:
10.0.0.1/24
192.168.10.0/24
172.16.30.1/24
我基本上试图计算“/”
的实例数这是我得到的输出:
###########
1
###########
我得到1而不是3,这是出现次数。 还在学习perl,所以任何帮助都会受到赞赏。谢谢!!
答案 0 :(得分:1)
关闭,但有几个问题:
use strict;
use warnings;
sub countModule
{
my $file = "/test";
open my $fh, "<",$file or die "could not open $file: $!";
my @contents = <$fh>; # The <> brackets are used to read from $fh.
my @filtered = grep (/\// ,@contents);
return @filtered; # Remove the reference.
}
my @lines = countModule();
my $count = scalar @lines; # 'scalar' is not required, but lends clarity.
print "###########\n $count \n###########\n";
我对您的代码所做的每项更改都使用#comment进行了注释,以解释已完成的操作。
现在在列表上下文中,子例程将返回已过滤的行。在标量上下文中,它将返回过滤了多少行的计数。
您还提到了查找字符的出现(尽管您的脚本中的所有内容都是面向行的)。也许你的反击子看起来像这样:
sub file_tallies{
my $file = '/test';
open my $fh, '<', $file or die $!;
my $count;
my $lines;
while( <$fh> ) {
$lines++;
$count += $_ =~ tr[\/][\/];
}
return ( $lines, $count );
}
my( $line_count, $slash_count ) = file_tallies();
答案 1 :(得分:1)
以下是关于您的代码的几点
您应该始终 use strict
位于程序的顶部,并且仅在有限范围内因特殊原因使用no warnings
。工作的Perl程序应该需要全局禁用警告
声明您的变量接近其第一个使用点。在文件顶部声明所有内容的样式是不必要的,并且是C
从不在代码中使用原型。它们可用于非常特殊的目的,不应用于绝大多数Perl代码。 sub countModule() { ... }
坚持countModule
可能永远不会使用任何参数调用,并且不是必需或有用的。定义应该只是sub countModule { ... }
一个很好的做得好!使用词法文件句柄,三参数形式的open,并将$!
放入你的死亡字符串
my @contents = $fh
只会将@contents
设置为仅包含文件句柄的单个元素列表。要将整个文件读入数组,您需要my @contents = <$fh>
如果使用不同的分隔符,则可以避免在正则表达式中转义斜杠。为此,您需要明确使用m
运算符,例如my @filtered = grep m|/|, @contents)
返回数组引用但将返回的值赋给数组,因此@lines = countModule()
将@lines
设置为仅包含数组引用的单元素列表。您应该返回包含return @filtered
的列表,或者使用@lines = @{ countModule }
取消引用返回值
如果您只需要打印文件中包含斜杠字符的行数,那么您可以编写类似这样的内容
use strict;
use warnings;
my $count;
sub countModule {
open my $fh, '<', '/test' or die "Could not open $file: $!";
return [ grep m|/|, <$fh> ];
}
my $lines = countModule;
$count = @$lines;
print "###########\n $count \n###########\n";
答案 2 :(得分:0)
在列表上下文中,
return \@filtered;
返回一个包含一个元素的列表 - 对指定数组@filtered
的引用。也许你想要自己返回列表
return @filtered;
答案 3 :(得分:-1)
这是一些更简单的代码:
sub countMatches {
my ($file, $c) = @_; # Pass parameters
local $/;
undef $/; # Slurp input
open my $fh, "<",$file or die "could not open $file: $!";
my $s = <$fh>; # The <> brackets are used to read from $fh.
close $fh;
my $ptn = quotemeta($c); # So we can match strings like ".*" verbatim
my @hits = $s =~ m/($ptn)/g;
0 + @hits
}
print countMatches ("/test", '/') . "\n";
代码推动Perl超越了基础,但不是太多。突出点:
通过取消$ /,您可以将输入读入一个字符串。如果你在数数 在文件中出现字符串,而不是出现包含的行 字符串,通常更容易做到。
m /(...)/ g会找到所有的点击数,但是如果你想计算字符串就像 “”你需要在其中引用元字符。
将结果存储在数组中以评估列表上下文中的m //
将0添加到列表中会显示其中的项目数。