2009-05-07 21 views
1

Der folgende Code erzeugt eine Liste der durchschnittlichen Anzahl von Clients durch Subnetz verbunden. Momentan muss ich es durch sort | uniq | grep -v HASH pipen.Wie komme ich zu meinen anonymen Arrays?

Der Versuch, alles in Perl zu halten dies nicht funktioniert:

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

Quelle ist dies:

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"; 
     } 
    } 

Wie kann ich die Notwendigkeit, dass die Art beseitigen | uniq-Prozess außerhalb von Perl? Der letzte foreach erhält die Subnetz-IDs, die die 'anonymen' Namen für die Arrays sind. Es wird mehrmals generiert (eine für jeden Tag, an dem das Subnetz verwendet wurde).

+0

Versuchen Sie, nur um sie zu drucken? Sehen Sie sich Data :: Dumper an. –

+0

Welcher Teil Ihres Codes funktioniert, welcher Teil nicht? Was versuchst du zu erreichen? – innaM

+1

Ich bin nicht sicher, was die Frage ist. Debugging-Code wäre einfacher mit Strikturen, obwohl: Verwenden Sie strikte; Verwenden Sie Warnungen; (strikt wird wollen Sie Ihre Variablen mit 'meine') – Anonymous

Antwort

2

aber das schien einfacher als Tabellenkalkulationen in Excel zu kombinieren.

Eigentlich machen Module wie Spreadsheet::ParseExcel das wirklich einfach, in den meisten Fällen. Sie müssen sich immer noch mit Zeilen wie mit CSV oder der Adressierung vom Typ "A1" beschäftigen, aber Sie müssen den Export-Schritt nicht durchführen. Und dann können Sie mit Spreadsheet::WriteExcel ausgeben!

Ich habe diese Module lesen eine Tabelle von einigen hundert Schecks, zu sortieren und ordnen und Mungo den Inhalt und schreiben auf einen neuen für die Lieferung an einen Buchhalter verwendet.


In diesem Teil:

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

$ Subnetz ist eine Zeichenfolge, aber Sie verwenden sie in der letzten Anweisung als Array Referenz. Da Sie auf nicht strictures haben, es behandelt sie als weiche Verweis auf eine Variable mit dem Namen der gleiche wie der Inhalt von $ Subnetz. Was ist in Ordnung, wenn Sie wirklich wollen, aber es ist verwirrend. Wie zur Klärung der letzten Teil ...

Update Ich vermute, das ist, was Sie suchen, wo der Subnetz-Wert nur gespeichert wird, wenn es nicht zuvor, auch von einem anderen Tag (?):

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

Als ich die csv-Dateien erzeugte, dachte ich, es wäre einfacher, einen zusätzlichen Schritt zu eliminieren. Danke für die Links. –

+0

@ Anonymous, das ist sauberer, aber es gibt mir immer noch 1667 Datensätze, die nach dem Durchlaufen von Sortieren und uniq auf 196 herunterkommen. Was ich möchte ist eine Möglichkeit, auf die Subnetz-Werte zugreifen einmal ... –

+0

@ Anonym, das ist viel besser, aber gibt mir immer noch die HASH (0xab5954) Arten von Antworten. Ich denke, das Beste wäre, die anonymen Arrays irgendwie zu eliminieren. –

0

@ Anregungen Anonymous Aufbauend auf, baute ich einen Hash der Subnetz Namen der Arrays acess:

..

  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 
} 

Nicht sicher, ob dies die beste Lösung ist, aber ich habe die Duplikate nicht mehr.

Verwandte Themen