der.milchjieper Geschrieben 11. März 2020 Geschrieben 11. März 2020 (bearbeitet) Guten Morgen zusammen, ich habe ein Aufgabe in PERL bekommen, ich arbeite auf einem uralten UNIX AIX System und kann nur auf eine geringe Anzahl von PERL-Modulen zugreifen da durch Compliance-Regeln der IT-Sec echt ängstlich ist. Aber jetzt zum Topic: Ich habe das Problem, dass ich in UNIX/Linux Case Sensitive Dateinamen habe, d.h. es kann vorkommen, dass eine Datei mit "gleichem Namen" 2x auftaucht, ich aber die Jüngste brauche und ich kann in meiner Subroutine die Bedingung dafür nicht ordentlich formulieren, da ich schon Knoten im Hirn habe und für mich PERL echtes Neuland ist. Könnt Ihr mir da irgendwie helfen? #!/usr/bin/perl -w use strict; use warnings; use File::Stat; use File::Copy; use POSIX; use Data::Dumper; # Dieses Skript MUSS im Verzeichnis der gesuchten Daten liegen, da sonst der # LastModifikation-Stamp nicht eingelesen wird my $directory = '/home/wizzard/caseSens/xml'; my $bak_directory = '/home/wizzard/caseSens/OLD'; my $filename; my $lastmod_on_file; my $key; my %filenames_and_timestamps; my %temphash; my %hash_ref; opendir DIR_HANDLE, $directory || die "Can not open directory $directory: $!"; while ( $filename = readdir DIR_HANDLE ) { next unless $filename =~ /\.xml$/; # Alle XML Dateien werden gelesen next if $filename =~ /^\./; # "Punkt"-Dateien überspringen # $filename = "$directory/$filename"; # Verzeichnis hinzufügen #LastModifed Stamp wird ermittelt my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat ($filename); $lastmod_on_file = $mtime; # Die Hashmap wird mit allen Bedingungen befüllt $filenames_and_timestamps{ $filename } = $lastmod_on_file; } &filename_and_lastmod_sort(); closedir DIR_HANDLE; ######################################################################### # PROZESS LOGIK ######################################################################### # # Alle Dateinamen stehen als Key in der Hash # das Last Modified Date ist die Value # # Der Hash steht nur noch als Referenz zur Verfügung, und zwar wie folgt # # # Doppelte Dateinamen finden in dem ein PatternMatching von DateiEbene # auf das Hash zeig, und anhand des Matching den Key findet. # # Allerdings kann es durchaus sein, dass durch CaseSensible ZWEI Keys gefunden # werden die sich nur durch Groß- und Kleinschreibung unterscheden. # Diese werden anhand der Value (LastModifed Date) sortiert und # das Jüngste/Neueste, unabhängig von Groß- und Kleinschreibung, wird dann behalten. # # # Ältere Daten werden verschoben in OLD # # # Hash wird Sortiert nach Key im UPPERCASE und dann nach Timestamp # Die jeweils älteste Datei wird verschoben in ein "OLD" Verzeichnis. # # Daten die bei denen es keine neuere Version gibt in "alter Schreibeweise ACECadPart-xxxxxxxx" werden # in UPPERCASE umbenannt # sub filename_and_lastmod_sort { # sortiert alphanummerisch nach dem Key # UND bei Gleichheit nummerisch absteigend nach der Value. # print "\n\nAlle Datein werden nach Filename sortiert\nund absteigend nach Datum\n"; foreach my $key ( sort { uc($a) cmp uc($b) || $filenames_and_timestamps{ $b } <=> $filenames_and_timestamps{ $a } } keys %filenames_and_timestamps) { # Ab hier soll ein weiteres Hash befüllt werden mit den jüngsten Daten printf "%-8s %s\n", $key, $filenames_and_timestamps{$key}; #&bereinigung($filenames_and_timestamps{$key}); } &bereinigung(); } # # Hier liegt für mich der Hund begraben, da ich die Syntaktische Bedingung in Perl nicht formulieren kann, ich nutze nur VIM und kann nicht wirklich #debuggen # sub bereinigung { if ( $filenames_and_timestamps{$key} <= ($b) ) { print "hello world\n"; }else{ print "goobye\n"; } } print "\nHash unberührt \n"; print Dumper(\%filenames_and_timestamps); print "\nTempHash bereinigt \n"; print Dumper(\%temphash); Das hier sind die Beispieldaten mit denen ich Arbeite : Terminalausgabe: Hash unberührt $VAR1 = { 'ACECadPart-M00000000008R3.xml' => 1583240787, 'ACECADPart-M00000000001R3.xml' => 1583240831, 'ACECADPart-M00000000004R3.xml' => 1583240800, 'ACECADPart-M00000000006R3.xml' => 1583741482, 'ACECADPart-M00000000007R3.xml' => 1583240813, 'ACECADPart-M00000000002R3.xml' => 1583240796, 'ACECadPart-M00000000004R3.xml' => 1583742311, 'ACECadPart-M00000000002R3.xml' => 1583240764, 'ACECADPart-M00000000003R3.xml' => 1583240822, 'ACECadPart-M00000000001R3.xml' => 1583240792, 'ACECadPart-M00000000003R3.xml' => 1583240756, 'ACECadPart-M00000000006R3.xml' => 1583240777, 'ACECadPart-M00000000007R3.xml' => 1583240782, 'ACECADPart-M00000000008R3.xml' => 1583240817, 'ACECADPart-M00000000005R3.xml' => 1583240804, 'ACECadPart-M00000000005R3.xml' => 1583240772 }; Alle Datein werden nach Filename sortiert und absteigend nach Datum ACECADPart-M00000000001R3.xml 1583240831 ACECadPart-M00000000001R3.xml 1583240792 ACECADPart-M00000000002R3.xml 1583240796 ACECadPart-M00000000002R3.xml 1583240764 ACECADPart-M00000000003R3.xml 1583240822 ACECadPart-M00000000003R3.xml 1583240756 ACECadPart-M00000000004R3.xml 1583742311 ACECADPart-M00000000004R3.xml 1583240800 ACECADPart-M00000000005R3.xml 1583240804 ACECadPart-M00000000005R3.xml 1583240772 ACECADPart-M00000000006R3.xml 1583741482 ACECadPart-M00000000006R3.xml 1583240777 ACECADPart-M00000000007R3.xml 1583240813 ACECadPart-M00000000007R3.xml 1583240782 ACECADPart-M00000000008R3.xml 1583240817 ACECadPart-M00000000008R3.xml 1583240787 Bearbeitet 11. März 2020 von der.milchjieper Detailänderung Zitieren
_n4p_ Geschrieben 21. März 2020 Geschrieben 21. März 2020 Moin, keine Ahnung ob das noch relevant ist und mein PERL ist deutlich eingerostet, es gibt also vermutlich bessere Lösungen Ich würde das auch andersrum angehen. Ich würde die Dateien zunächst "falsch" herum sortieren, so das die neueste Datei immer die letzte ist. Das Ergebnis schiebe ich erstmal in ein temporären Hash mit dem uppercase Filename als key. $tmp{uc($key)} = [ $key, $filenames_and_timestamps{$key} ]; daraus bastel ich dann den temphash und sortiere bei bedarf nochmal in der richtigen Reihenfolge foreach my $key (keys %tmp) { $temphash{$tmp{$key}[0]} = $tmp{$key}[1]; } sicher nicht sonderlich effizient, aber das versteh ich auch in 6 Monaten noch Zitieren
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.