Как добраться до моих анонимных массивов? - PullRequest
1 голос
/ 07 мая 2009

Следующий код генерирует список среднего числа клиентов, подключенных по подсети. В настоящее время я должен передать это через sort | uniq | grep -v HASH.

Попытка сохранить все это в Perl, это не работает:

foreach $subnet (keys %{keys %{keys %days}}) {
    print "$subnet\n";
}

Источник такой:

foreach $file (@ARGV) {
        open(FH, $file) or warn("Can't open file $file\n");
        if ($file =~ /(2009\d{4})/) {
            $dt = $+;
        }
        %hash = {};
        while(<FH>) {
            @fields = split(/~/);
            $subnet = $fields[0];
            $client = $fields[2];
            $hash{$subnet}{$client}++;
        }
        close(FH);
        $file = "$dt.csv";
        open(FH, ">$file") or die("Can't open $file for output");
        foreach $subnet (sort keys %hash) {
                $tot = keys(%{$hash{$subnet}});
                $days{$dt}{$subnet} = $tot;
                print FH "$subnet,$tot\n";
                push @{$subnet}, $tot;
        }
        close(FH);
    }

    foreach $day (sort keys %days) {
        foreach $subnet (sort keys %{$days{$day}}) {
            $tot = $i = 0 ;
            foreach $amt (@{$subnet}) {
                $i++;
                $tot += $amt;
            }
            print "$subnet," . int($tot/$i) . "\n";
        }
    }

Как мне устранить необходимость в сортировке | Uniq процесс за пределами Perl? Последний foreach возвращает мне идентификаторы подсетей, которые являются «анонимными» именами массивов. Он генерирует их несколько раз (по одному на каждый день, когда использовалась подсеть).

Ответы [ 2 ]

2 голосов
/ 07 мая 2009

но это казалось проще, чем объединять таблицы в Excel.

На самом деле, такие модули, как Spreadsheet :: ParseExcel , делают это действительно легко, в большинстве случаев. Вы по-прежнему должны иметь дело со строками, как будто из адресации CSV или типа «A1», но вам не нужно делать шаг экспорта. И тогда вы можете вывести с помощью Spreadsheet :: WriteExcel !

Я использовал эти модули, чтобы прочитать электронную таблицу из нескольких сотен чеков, отсортировать и упорядочить содержимое, а также написать в новый для доставки бухгалтеру.


В этой части:

foreach $subnet (sort keys %hash) {
        $tot = keys(%{$hash{$subnet}});
        $days{$dt}{$subnet} = $tot;
        print FH "$subnet,$tot\n";
        push @{$subnet}, $tot;
}

$ subnet - это строка, но вы используете ее в последнем выражении в качестве ссылки на массив. Поскольку у вас нет strictures , он обрабатывает его как мягкую ссылку на переменную с именем, совпадающим с содержимым $ subnet. Что хорошо, если вы действительно хотите, но это сбивает с толку. Что касается уточнения последней части ...

Обновление Я предполагаю, что это то, что вы ищете, где значение подсети сохраняется, только если оно не появилось раньше, даже из другого дня (?):

use List::Util qw(sum); # List::Util was first released with perl 5.007003 (5.7.3, I think)
my %buckets;
foreach my $day (sort keys %days) {
    foreach my $subnet (sort keys %{$days{$day}}) {
        next if exists $buckets{$subnet}; # only gives you this value once, regardless of what day it came in
        my $total = sum @{$subnet}; # no need to reuse a variable
        $buckets{$subnet} = int($total/@{$subnet}; # array in scalar context is number of elements
    }
}

use Data::Dumper qw(Dumper);
print Dumper \%buckets;
0 голосов
/ 07 мая 2009

Основываясь на предложениях @ Anonymous, я создал хеш имен подсетей для доступа к массивам:

..

            push @{$subnet}, $tot;
            $subnets{$subnet}++;
    }
    close(FH);
}

use List::Util qw(sum); # List::Util was first released with perl 5.007003

foreach my $subnet (sort keys %subnets) {
    my $total = sum @{$subnet}; # no need to reuse a variable
    print "$subnet," . int($total/@{$subnet}) . "\n"; # array in scalar context is number of elements
}

Не уверен, что это лучшее решение, но у меня больше нет дубликатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...