DasFaultier Geschrieben 22. März 2010 Teilen Geschrieben 22. März 2010 Hallo zusammen, ich habe die Aufgabe, ein Logfile (plaintext) von unserem Speichersystem auszuwerten. Das Logfile beinhaltet jeweils den Namen des aktuellen Ordners und die dazu gehörigen Dateien samt Größe und Speicherort (HDD / Tape Library). Um herauszufinden, welcher (Unter-)Ordner wie viel Speicherplatz verbraucht, habe ich mehrere "Programme" (in bash + awk, in Perl und in einem Excel-Sheet) geschrieben, die das Logfile auswerten und den Speicherverbrauch ähnlicher Ordner aufaddieren. Außerdem weiß ich, dass die Werte, die mir Excel liefert, die Richtigen sind. Leider bekomme ich bei meinen anderen Scripten zwar immer die ungefähr richtige Größenordnung heraus, die Ergebnisse unterscheiden sich je nach Speicherort aber um Größenordnungen von ca. 200 MB bzw. 70 GB. Ich würde nun gerne wissen, woher diese Ungenauigkeit kommen könnte. Überläufe in den Wertebereichen konnte ich bereits ausschließen. Hatte vielleicht schon einmal jemand ein ähnliches Problem? Wo könnten die Ursachen liegen? Ich bin für jede Hilfe dankbar. Bei Bedarf könnte ich natürlich auch gerne mal den Code posten. Vielen Dank und liebe Grüße, euer Faultier Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bigvic Geschrieben 22. März 2010 Teilen Geschrieben 22. März 2010 Bei Bedarf könnte ich natürlich auch gerne mal den Code posten. Wie sonst soll ein debugging möglich sein? Am Rande ... wenn du eh perl benutzt, warum dann noch bash/awk? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
DasFaultier Geschrieben 22. März 2010 Autor Teilen Geschrieben 22. März 2010 (bearbeitet) Hi! Tatsache ist, dass ich das Ganze erst in Bash / awk gemacht hab' und erst dann zu Perl umgeschwenkt bin, um 'ne befriedigendere Lösung zu erhalten. Hat nur leider nicht so geklappt, wie ich mir das gedacht hab'. Außerdem zielte meine Frage auch eher auf allgemeine Gründe ab (wie z.B. ein Überlauf des Wertebereichs einer sein könnte) als auf konkrete Fehler im Quellcode. Nichtsdestotrotz hier der Perl-Code: #!/usr/bin/perl ####################### # Includes # ####################### use English; use HelpTools; #eigenes Modul use strict; no strict "refs"; use utf8; ####################### # Deklarationsteil # ####################### #Std.-Skalare my $Source = "out.txt"; my $RegExSource = "prep.txt"; my $Dest = "summ.txt"; my $Diag = 0; # Diagnoseausgaben (0 = AUS, 1 = AN) my $Errors = 0; my $aktRegex = ""; my $aktZeile = ""; #Zähler my $SizeHDD = 0; my $SizeBand = 0; my $countHDD = 0; my $countBand = 0; my $durchsuchte = 0; #Arrays my @Regexe; #Hashes my %count; #zählt für jeden Regex die Anzahl der gefundenen Zeilen => vielleicht finden wir dadurch raus, wo die Speicherdifferenzen herkommen ####################### # Implementationsteil # ####################### #Dateihandles oeffnen sub openHandles(){ #Quelldatei öffnen if (-e $Source){ #Falls Datei existiert if (open (SOURCE_HANDLE, '<' , $Source)){print "Quelldatei \"$Source\" erfolgreich geoeffnet.\n" if ($Diag)} #falls das Öffnen klappt else {die "Die Quelldatei \"$Source\" konnte nicht geoeffnet werden: $!.\n";} #sonst Fehler melden } else {print "Die Quelldatei \"$Source\" existiert nicht: $!.\n";} #sonst Fehler melden #Quelle für Regular Expressions öffnen if (-e $RegExSource){ #Falls Datei existiert if (open (REGEX_HANDLE, '<' , $RegExSource)){print "Regex-Quelldatei \"$RegExSource\" erfolgreich geoeffnet.\n" if ($Diag)} #falls das Öffnen klappt else {die "Die Regex-Quelldatei \"$RegExSource\" konnte nicht geoeffnet werden: $!.\n";} #sonst Fehler melden } else {print "Die Regex-Quelldatei \"$RegExSource\" existiert nicht: $!.\n";} #sonst Fehler melden #Zieldatei öffnen if (open (DEST_HANDLE, '>' , $Dest)){print "Zieldatei \"$Dest\" erfolgreich geoeffnet.\n" if ($Diag)} #falls das Öffnen klappt else {die "Die Zieldatei \"$Dest\" konnte nicht geoeffnet werden: $!.\n";} #sonst Fehler melden return 1; } #Dateihandles schliessen sub closeHandles(){ #Dateihandles schließen unless (close SOURCE_HANDLE) {die "Das Dateihandle zur Datei \"$Source\" konnte nicht geschlossen werden: $!.\n"; $Errors++;} unless (close REGEX_HANDLE) {die "Das Dateihandle zur Datei \"$RegExSource\" konnte nicht geschlossen werden: $!.\n"; $Errors++;} unless (close DEST_HANDLE) {die "Das Dateihandle zur Datei \"$Dest\" konnte nicht geschlossen werden: $!.\n"; $Errors++;} if ((!$Errors) && ($Diag)){print "Alle Dateihandles erfolgreich geschlossen. Programm wird beendet.\n";} return 1; } #Ergebnisse in die Ausgabedatei schreiben sub Ausgabe(){ print DEST_HANDLE "$_[0]\t\t$countBand\t$SizeBand\t$countHDD\t$SizeHDD\n"; #print "$aktRegex\t$countHDD\t$SizeHDD\t$countBand\t$SizeBand\n"; return 1; } #alle RegExes aus Datei in ein Array übertragen sub prepareRegex(){ #Regexe aus Datei lesen while (<REGEX_HANDLE>){ chomp; push (@Regexe, $_); } #Diagnoseausgabe if ($Diag){ foreach my $Regex (@Regexe){ print DEST_HANDLE "REGEXE: " . $Regex . "\n"; } print DEST_HANDLE "======================================================================================\n"; } return 1; } &openHandles(); &prepareRegex(); print DEST_HANDLE "Ordnername\tAnzahlBand\tGroesseBand\tAnzahlPlatte\tGroessePlatte\n\n"; foreach my $Regex (@Regexe){ if ($Regex ne ""){ seek(SOURCE_HANDLE, 2, 0); #seek(DATEIHANDLE, Zeilennummer (ab 1 indiziert), Offset); while (<SOURCE_HANDLE>){ #chomp; #print "Zeile: " . $_ . "\n"; $aktZeile = $_; #Beispielzeile: san-work-goobi-backup.dir 14 4032 2 2.72933e+09 #if ($aktZeile =~ m/$aktRegex/gi){ if ($aktZeile =~ m/$Regex\t/gi){ #$aktZeile =~ m/\t(\d+)/gi; #Spalte 1 $aktZeile =~ m/(\d+)\t(\d\.?\d+e\+\d{2}|\d+)\t(\d+)\t(\d\.?\d+e\+\d{2}|\d+)/gi; $countHDD += $1; $SizeHDD += $2; $countBand += $3; $SizeBand += $4; $count{$Regex} += 1; } $durchsuchte++; # = Regexe * zu pruefende Zeilen } &Ausgabe($Regex); #Zaehlvariablen fuer naechsten Unterordner zuruecksetzen $SizeHDD = 0; $SizeBand = 0; $countHDD = 0; $countBand = 0; } } print DEST_HANDLE "Durchsuchte: $durchsuchte." if ($Diag); while ( my ($k,$v) = each %count ) { print "$k => $v\n"; } &closeHandles(); Der AWK-Code sieht so aus: BEGIN { AnzB=0; AnzP=0; SizeB=0; SizeP=0; #OFMT="%.15g"; #Output Format OFMT="%i"; #Output Format } AnzB+=$4; AnzP+=$2; SizeB+=($5); # kommt in Bytes aus der Datei SizeP+=($3); # kommt in Bloecken zu je 1 kB aus der Datei END { print(Arg " " AnzB " " SizeB " " AnzP " " SizeP); } Die verwendeten Dateien. out.txt sieht auszugsweise so aus: Name AnzahlHDD GroesseHDD AnzahlBand GroesseBand san-work-goobi-backup.dir 14 4032 2 2729330665 san-work-goobi-collect-2nd 6 24 0 0 san-work-goobi-collect-aix 1 1096 0 0 san-work-goobi-collect-hp11 1 1104 0 0 san-work-goobi-collect-linux86 1 748 0 0 ... hier folgen weitere prep.txt sieht auszugsweise so aus: backup.dir collect collect-2nd collect-aix collect-hp11 collect-linux86 collect-solaris ... hier folgen weitere So, ich hoffe, ich hab' erst mal nix vergessen. Vielen Dank übrigens für deine schnelle Antwort! Bis bald, DasFaultier EDIT: Hab' natürlich doch noch was vergessen. Erstens das Aussehen der summ.txt, die da entstehen soll: Ordnername AnzahlBand GroesseBand AnzahlPlatte GroessePlatte backup.dir 2 2729330665 14 4032 collect 0 0 10 4556 collect-2nd 0 0 6 24 collect-aix 0 0 1 1096 collect-hp11 0 0 1 1104 collect-linux86 0 0 1 748 collect-solaris 0 0 1 1180 collect-work05 0 0 1 440 ... hier folgen weitere und zweitens das Bash-Script: #!/bin/bash #Verwendung: "./summ.sh" #WICHTIG: Da die Datei "sehrKurzeVerzeichnisliste.txt" ausgewertet wird, müssen Sie durch Aufruf des Programms "kompletteVerzeichnisListe.sh" sicherstellen, dass diese auch existiert. sed "s/^-//gi" sehrKurzeVerzeichnisliste.txt | sed "s/\s/_/gi" > prep.txt echo "Ordnername AnzahlBand GroesseBand AnzahlPlatte GroessePlatte"; echo; for ELEMENT in `more prep.txt`; do ELEMENT="$ELEMENT "; # Tabulator anfuegen, um nur Wurzelverzeichnisse zu triggern (alle Unterverzeichnisse bleiben unangetastet) grep -e "${ELEMENT}" out.txt | gawk -v Arg="${ELEMENT}" -f ./summ.awk | grep -v "san-"; done #rm prep.txt; #Kommentierung entfernen, um temporäre Datei "prep.txt" nach Ausführung des Scriptes zu löschen Als kurze Erklärung vielleicht noch: out.txt ist das Ergebnis des ersten Zwischenschrittes der Berechnungen. Die Ergebnisse in dieser Datei sind verifiziert und richtig. Hier wird der verwendete Speicherplatz pro Unterverzeichnis aufaddiert. In prep.txt liegen verkürzte Pfade aller ähnlich klingenden Unterverzeichnisse. summ.txt enthält dann die Summe des Speicherplatzes aller ähnlich klingenden Unterverzeichnisse. Bearbeitet 22. März 2010 von DasFaultier Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.