Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

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

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 von DasFaultier

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.