Sprache auswählen

© Borgmann Aquaponik & Hydroponik
Alle Rechte Vorbehalten
https://borgmann-aquaponik-hydroponik.ch

Viel Erfolg wünschen wir Ihnen!

Haftungsausschluss

Die Nutzung dieser Software erfolgt auf eigene Gefahr. Der Anbieter übernimmt keine Haftung für Schäden, die direkt oder indirekt durch die Verwendung der Software entstehen, einschließlich, aber nicht beschränkt auf Datenverlust, Systemausfälle oder wirtschaftliche Schäden. Die Software wird „wie sie ist“ bereitgestellt, ohne jegliche Gewährleistung oder Garantie, weder ausdrücklich noch stillschweigend, einschließlich, aber nicht beschränkt auf die Garantie der Marktgängigkeit oder der Eignung für einen bestimmten Zweck. Der Anbieter behält sich das Recht vor, die Software jederzeit ohne vorherige Ankündigung zu ändern, zu aktualisieren oder einzustellen.


Zweck: Dateien prüfen wenn sie das Betriebssystem wechseln (Linux -> NextCloud etwa)
Suche nach Dateien und Verzeichnissen mit system-inkompatiblen Zeichen...
KORREKTUR-MODUS: Problematische Zeichen werden korrigiert (mit Rückfrage)
NUR ANZEIGE - keine Änderungen werden durchgeführt!

Sucht nach:
    # 1. Steuerzeichen und Null-Zeichen + entfernen
    # 2. Windows-reservierte Zeichen + ersetzen
    # 3. Nextcloud-problematische Zeichen + ersetzen
    # 4. macOS-problematische Zeichen + ersetzen


Optionen:
  -f, --fix        Problematische Zeichen korrigieren (mit Rückfrage)
  -h, --help       Diese Hilfe anzeigen


Auf eigene Gefahr !
Viel Spaß, helmer


#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use Getopt::Long;

my $fix = 0;
my $help = 0;

# Hilfe-Text
my $help_text = <<'END_HELP';
Dateinamen-Checker für Multi-System-Kompatibilität

Verwendung: $0 [Optionen] [Verzeichnis...]

Optionen:
  -f, --fix        Problematische Zeichen korrigieren (mit Rückfrage)
  -h, --help       Diese Hilfe anzeigen

Geprüfte Systeme:
  Linux, Windows, macOS, Nextcloud

Mit --fix werden folgende Zeichen korrigiert (nach Rückfrage):
  \\ : * ? " < > | # % Steuerzeichen Leerzeichen-am-Ende
END_HELP

# Optionen verarbeiten
GetOptions(
    'fix|f'         => \$fix,
    'help|h'        => \$help
);

if ($help) {
    print $help_text;
    exit 0;
}

my @directories = @ARGV ? @ARGV : ('.');

print "Suche nach Dateien und Verzeichnissen mit system-inkompatiblen Zeichen...\n";
if ($fix) {
    print "KORREKTUR-MODUS: Problematische Zeichen werden korrigiert (mit Rückfrage)\n";
} else {
    print "NUR ANZEIGE - keine Änderungen werden durchgeführt!\n";
}
print "\n";

my @problem_files;
my $fix_confirmed = 0;
my $total_fixed = 0;

find({
    wanted => sub {
        my $filename = $_;
        my $full_path = $File::Find::name;
        my $dir_path = $File::Find::dir;
        
        # Überspringe . und .. Verzeichnisse
        return if $filename eq '.' || $filename eq '..';
        
        # Prüfe auf Probleme für verschiedene Systeme
        my @problems = check_system_problems($filename);
        
        if (@problems) {
            my $new_name = sanitize_filename($filename);
            
            push @problem_files, {
                path => $full_path,
                dir => $dir_path,
                is_dir => (-d $full_path) ? 1 : 0,
                problems => \@problems,
                original_name => $filename,
                new_name => $new_name
            };
            
            my $type = (-d $full_path) ? "VERZEICHNIS" : "DATEI";
            print "PROBLEM ($type): $full_path\n";
            
            # Detaillierte Problembeschreibungen
            foreach my $problem (@problems) {
                print "  - $problem->{system}: $problem->{description}\n";
            }
            
            # Zeige Vorschlag für bereinigten Namen
            if ($new_name ne $filename) {
                print "  KORREKTUR-VORSCHLAG: '$filename' -> '$new_name'\n";
            }
            
            # Korrektur-Logik
            if ($fix && $new_name ne $filename) {
                my $new_path = $dir_path . '/' . $new_name;
                
                # Sicherheitsabfrage für jede Datei
                print "  Korrigieren? (j/n/a für alle): ";
                my $answer = <stdin>;
                chomp $answer;
                
                if ($answer =~ /^a$/i) {
                    $fix_confirmed = 1;
                }
                
                if ($answer =~ /^j$/i || $fix_confirmed) {
                    print "  Versuche Umbenennung:\n";
                    print "  Von: $full_path\n";
                    print "  Nach: $new_path\n";
                    
                    if (rename($full_path, $new_path)) {
                        print "  ✓ KORRIGIERT: '$new_name'\n";
                        $total_fixed++;
                    } else {
                        warn "  ✗ FEHLER: Konnte nicht umbenennen: $!\n";
                        print "  Stelle sicher dass die Datei existiert und Sie Schreibrechte haben.\n";
                    }
                } else {
                    print "  ✗ ÜBERSPRUNGEN: Keine Korrektur durchgeführt\n";
                }
            }
            print "\n";
        }
    },
    no_chdir => 1
}, @directories);

# Zusammenfassung
if (!@problem_files) {
    print "Keine Dateien oder Verzeichnisse mit Kompatibilitätsproblemen gefunden.\n";
} else {
    print "\n" . ("=" x 60) . "\n";
    print "ZUSAMMENFASSUNG:\n";
    print "Dateien/Verzeichnisse mit Problemen: " . scalar(@problem_files) . "\n";
    
    # Problemstatistik nach System
    my %system_stats;
    my $total_problems = 0;
    
    foreach my $item (@problem_files) {
        foreach my $problem (@{$item->{problems}}) {
            $system_stats{$problem->{system}}++;
            $total_problems++;
        }
    }
    
    print "Einzelne Problem-Meldungen gesamt: $total_problems\n\n";
    
    if ($fix) {
        print "Korrigierte Dateien: $total_fixed\n";
    } else {
        print "Um Korrekturen durchzuführen: $0 --fix [Verzeichnis]\n";
    }
    
    print "\nProblemverteilung nach System:\n";
    foreach my $system (sort keys %system_stats) {
        printf "  %-12s: %d Meldungen\n", $system, $system_stats{$system};
    }
}

exit 0;

# Prüft auf Probleme für verschiedene Systeme
sub check_system_problems {
    my $name = shift;
    my @problems;
    
    # LINUX Probleme
    if ($name =~ /\0/) {
        push @problems, {
            system => 'Linux',
            description => 'Enthält Null-Zeichen (\\0) - String-Terminator in C'
        };
    }
    
    if (length($name) > 255) {
        push @problems, {
            system => 'Linux',
            description => 'Name zu lang (' . length($name) . ' > 255 Zeichen) - Dateisystem-Limit'
        };
    }
    
    # WINDOWS Probleme
    if ($name =~ /[\\:*?"<>|]/) {
        my @bad_chars;
        push @bad_chars, '\\ (Backslash)' if $name =~ /\\/;
        push @bad_chars, ': (Doppelpunkt)' if $name =~ /:/;
        push @bad_chars, '* (Stern)' if $name =~ /\*/;
        push @bad_chars, '? (Fragezeichen)' if $name =~ /\?/;
        push @bad_chars, '" (Anführungszeichen)' if $name =~ /"/;
        push @bad_chars, '< (kleiner als)' if $name =~ /</;
        push @bad_chars, '> (größer als)' if $name =~ />/;
        push @bad_chars, '| (Pipe)' if $name =~ /\|/;
        
        push @problems, {
            system => 'Windows',
            description => 'Enthält reservierte Zeichen: ' . join(', ', @bad_chars)
        };
    }
    
    # Windows reservierte Namen
    my $name_without_ext = $name;
    $name_without_ext =~ s/\.[^.]+$//;
    my $upper_name = uc($name_without_ext);
    
    my @reserved_names = qw(CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9 LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9);
    foreach my $reserved (@reserved_names) {
        if ($upper_name eq $reserved) {
            push @problems, {
                system => 'Windows',
                description => "Reservierter Gerätename: $reserved"
            };
            last;
        }
    }
    
    # NEXTCLOUD Probleme
    if ($name =~ /[#%]/) {
        my @bad_chars;
        push @bad_chars, '# (Raute)' if $name =~ /#/;
        push @bad_chars, '% (Prozent)' if $name =~ /%/;
        
        push @problems, {
            system => 'Nextcloud',
            description => 'Problematisch für URLs: ' . join(', ', @bad_chars)
        };
    }
    
    # macOS Probleme (historisch)
    if ($name =~ /:/) {
        push @problems, {
            system => 'macOS',
            description => 'Doppelpunkt (:) war in HFS verboten'
        };
    }
    
    # ALLGEMEINE Probleme
    if ($name =~ /[\x00-\x1F\x7F]/) {
        push @problems, {
            system => 'Allgemein',
            description => 'Enthält Steuerzeichen (nicht druckbar)'
        };
    }
    
    if ($name =~ /^\s/) {
        push @problems, {
            system => 'Allgemein',
            description => 'Beginnt mit Leerzeichen - unsichtbar in manchen Systemen'
        };
    }
    
    if ($name =~ /\s$/) {
        push @problems, {
            system => 'Allgemein',
            description => 'Endet mit Leerzeichen - kann zu Problemen führen'
        };
    }
    
    if ($name =~ /\.$/) {
        push @problems, {
            system => 'Windows',
            description => 'Endet mit Punkt - in Windows verboten'
        };
    }
    
    return @problems;
}

# Erzeugt Vorschlag für bereinigten Namen
sub sanitize_filename {
    my $name = shift;
    
    # Sicherstellen dass wir nur den Dateinamen bearbeiten
    # Extrahiere nur den Basisnamen falls versehentlich ein Pfad übergeben wurde
    if ($name =~ /\//) {
        # Falls Pfad enthalten, nur den letzten Teil nehmen
        $name =~ m{([^/]+)$};
        $name = $1;
    }
    
    my $original = $name;
    
    # 1. Steuerzeichen und Null-Zeichen entfernen
    $name =~ s/[\x00-\x1F\x7F]//g;
    
    # 2. Windows-reservierte Zeichen ersetzen
    $name =~ s/[\\:*?"<>|]/_/g;
    
    # 3. Nextcloud-problematische Zeichen ersetzen
    $name =~ s/[#%]/_/g;
    
    # 4. macOS-problematische Zeichen ersetzen
    $name =~ s/:/_/g;
    
    # 5. Leerzeichen am Anfang/Ende entfernen
    $name =~ s/^\s+//;
    $name =~ s/\s+$//;
    
    # 6. Punkt am Ende entfernen (Windows)
    $name =~ s/\.$//;
    
    # 7. Reservierte Windows-Namen umbenennen
    my $name_without_ext = $name;
    my $ext = '';
    if ($name =~ /(.+)\.([^.]+)$/) {
        $name_without_ext = $1;
        $ext = '.' . $2;
    }
    
    my $upper_name = uc($name_without_ext);
    my @reserved_names = qw(CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9 LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9);
    foreach my $reserved (@reserved_names) {
        if ($upper_name eq $reserved) {
            $name_without_ext = $reserved . '_file';
            $name = $name_without_ext . $ext;
            last;
        }
    }
    
    return $name eq "" ? "umbenannt_" . time() : $name;
}

#
## Thats all