【问题标题】:Need help with a perl program在 perl 程序方面需要帮助
【发布时间】:2011-08-06 16:45:00
【问题描述】:

好的,所以我正在尝试使用哈希,如果数组中的任何字符串包含哈希中的键(不是值实际键名),则丢弃它。否则打印出字符串。此问题与 findHidden 子例程的一部分有关。我尝试了很多不同的东西,我会在下面评论我有问题的地方。我确定有人有答案,总是在堆栈溢出时得到一个:)

#!/usr/bin/perl
# Configure
use strict;
use warnings;
use Data::Dumper;
#
sub findHidden;
sub GetInfo; 
sub defineHash;
##############

$passwd = '/etc/passwd';
%info = ();

sub GetInfo {
        die "Cannot open: $passwd"
        unless (open(PW,$passwd));
        while(<PW>) {
                chomp;
                my ($uname,$junk1,$junk2,$junk3,$domain,$home) = split(':', $_);
                next unless ($home =~ /vs/);
                %info = (
                        domain  => $domain,
                        home    => "$home/",
                        tmp     => "$home/tmp",
                        htdocs  => "$home/www/htdocs",
                        cgibin  => "$home/www/cgi\-bin",
                );
                print "\n" . $info{domain} . "\n";
                print "+"x40,"\n\n";
                findHidden($info{tmp});
        }
}
sub findHidden {
        defineHash;
        print "Searching " . $_[0] . "\n";
        print "-"x30,"\n\n";
        @hidden = `find $_[0] -iname ".*"`;
        for(@hidden) {
                foreach $key (keys % hExcludes) {
                        if ($_ =~ /$key/){    #
                                last;         # This portion is 
                        }else{                # Only an issue when using more
                                print "$_";   # than 2 keys in my hash.
                                last;
                        }
                }
        }
}
sub defineHash {
        %hExcludes = ();
        %hExcludes = map { $_, 1 } (
                'spamd','.nfs'     # If I add another key here, it breaks.
        );

        %knownExploits = 
                ( );
        print Dumper \%hExcludes;
}
GetInfo;

This Works,并打印出如下内容:

/somedir/tmp/.testthis
/somedir/tmp/.sdkfbsdif
/somedir/tmp/.asdasdasd

我明白为什么它不工作,因为它循环通过一些是假的和一些是积极的键,我只是想不出如何让它做我想要的,请假设我可能想要你 10 个键.我知道有一些方法可以在不为我的排除项使用哈希键值的情况下做到这一点,但这是我想要完成的。

我也试过 shift @hidden 如下,但无济于事。

                foreach $key (keys % hExcludes) {
                        if ($_ =~ /$key/){    #
                                last;         #
                                shift @hidden;# This portion is 
                        }else{                # Only an issue when using more
                                print "$_";   # than 2 keys in my hash.
                                last;
                        }

另外,请记住,只有当我添加第三个...或更多键时,事情才会停止工作。

        %hExcludes = map { $_, 1 } (
                'spamd','.nfs','key3'     # If I add another key here, it breaks
        );

【问题讨论】:

  • 您只需要说出“它坏了”是什么意思吗?一个提示:您正在替换其值包含正则表达式中的元字符的变量,即“.nfs”。您可能想写 /\Q$key\E/ 以提供报价。
  • -1 您发布的代码不可能“工作”,因为它甚至无法编译。您应该确保发布与您运行的代码完全相同的代码!

标签: arrays perl loops hash shift


【解决方案1】:

你需要的是这个:

    @hidden = `find $_[0] -iname ".*"`;
    for(@hidden) {
        undef $isExcluded;
        foreach $key (keys % hExcludes) {
            if ($_ =~ /$key/){
                $isExcluded=1;
                last;
            }
        }
        if( ! $isExcluded ) {
            print "$_";
        }
    }

无论您在通过 hExcludes 的键扫描时发生了什么,代码在第一个键上遇到了 last 并且不再处理。您需要设置一个标志并继续迭代,直到没有更多要设置的键或找到匹配项。然后就可以打印出不匹配的值了。

【讨论】:

  • 问题,你觉得这种方法比不使用哈希键匹配更快吗?
  • 实际上您并没有真正使用哈希键,因为您放置哈希的唯一用途是创建一个唯一的正则表达式数组以再次测试。通过使用散列,您可以免费获得独特的测试,但必须花时间从散列创建一个数组,然后才能使用它。如果所需的测试是匹配显式文件名,即测试是$_==$key,那么它可以写得更快,如exists $hExcludes{$_},并且避免了内部循环。
  • 有道理,唯一的事情是我需要一个 if 不包含显式匹配。
猜你喜欢
  • 2011-05-09
  • 1970-01-01
  • 2012-12-21
  • 2015-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
相关资源
最近更新 更多