2017-12-05 2 views
0

Ich habe das folgende Shell-Skript entwickelt, um doppelte Teile des Dateinamens zu finden und zu löschen. Ähnlich muss ich in Perl-Skript auch als Perl-Skript Textverarbeitung dauert weniger Zeit vorbereiten.Perl Script Hilfe benötigt für doppelte Dateinamen

#!/bin/bash 
for i in `ls -t *xml|awk 'BEGIN{FS="_"}{if (++dup[$1] >= 2) print}'`; 
do 
rm $i 
done 

ich meine Perl-Skript meinen Code in einer solchen Art und Weise herzustellen, die nur den letzten modifizierten Dateinamen-Muster zum Beispiel

File 1: AAA_555_0000 
File 2: AAAA_123_123 
File 3: AAAA_452_452 [latest] 

File 4: BBB_555_0000 
File 5: BBB_555_555 
File 6: BBB_999_999 [latest] 

File 7: CCC_555_0000 
File 8: CCC_000_000 
File 9: CCC_000_111 [latest] 

Perl Script hat neueste Datei in allen Dateinamen-Muster wählen (bedeutet Teil von Dateiname) in dem Ordner und es sollte die Duplikate vergleichen und löschen. Zum Beispiel: Das Skript muss die letzte Datei im AAA-Dateinamenmuster auswählen und es muss mit anderen AAA-Mustern verglichen werden, wenn das Muster gefunden wurde, dass es gelöscht werden muss. am ende muss nur die letzte datei in allen filenamen beibehalten werden.

Schätzen Sie, wenn Sie mir mit dieser Logik helfen können.

Vielen Dank!

+4

Was ist der "_Dateiname patterns_" - welches Muster? Erste drei gleiche Charaktere? Oder solche, die mit 'A' beginnen, dann mit' B' ...? Bitte klären Sie (ich meine, bearbeiten Sie die Frage, um eine Erklärung hinzuzufügen) – zdim

+0

Antwort auf Sie. Das ist, was ich in Shell-Skript auch getan habe, indem ich field-Trennzeichen in awk verwende ich Teil des Dateinamens und verglichen mit anderen Dateinamen. – misterbean2

+0

Mit "doppelte Teile" meinen Sie führende Teile gleich oder irgendein Teil? "AAA_555_0000", "BBB_555_0000" und "CCC_555_0000" haben doppelte Teile. – shawnhcorey

Antwort

0

Ihre Frage ist mir etwas unklar, weil ich nicht sicher bin, wie Sie die Reihenfolge Ihrer Dateien bestimmen, um festzustellen, welches neuer ist. Dieser Code wird tun, was ich glaube, Sie brauchen:

my $dir = shift || '.'; 

opendir(my $dh, $dir); 
my @files = sort grep !/^\./, readdir($dh); 

my $last; 
my @batch; 
foreach my $f (@files) { 
    my @parts = split /_/, $f; 

    if(!$last) { 
    $last = $parts[0]; 
    push @batch, [ @parts ]; 
    } 
    elsif(index($last, $parts[0]) != -1) { 
    push @batch, [ @parts ]; 
    } 
    else { 
    delete_files(@batch); 

    @batch = ([ @parts ]); 
    $last = $parts[0]; 
    } 
} 
delete_files(@batch); 

sub delete_files { 
    my @batch = @_; 

    @batch = sort { 
    $a->[0] cmp $b->[0] || 
    $a->[1] cmp $b->[1] || 
    $a->[2] cmp $b->[2] 
    } @batch; 
    pop @batch; 

    map { print "Delete: ", join('_', @$_), "\n"; } @batch; 
} 

Es geht davon aus, dass eine Batch von Dateien ist eine, bei der Dateien mit dem gleichen Präfix haben (bis zum ersten ‚_‘ Zeichen). Wenn zwei Präfixe eine unterschiedliche Länge haben, muss die gemeinsame Länge übereinstimmen.

Es wird auch davon ausgegangen, dass "Versionsnummern" (Textbits getrennt durch "_") verglichen werden sollten, wobei die linke am deutlichsten ist.

diese Annahmen, der Code gegeben, in einem Verzeichnis mit den Dateien darauf Sie erwähnen, Ausgänge:

# latest.pl <dir> 
Delete: AAA_555_0000 
Delete: AAAA_123_123 
Delete: BBB_555_0000 
Delete: BBB_555_555 
Delete: CCC_000_000 
Delete: CCC_000_111 

Die unklare Teil ist, warum Sie denken, dass Datei 7 nicht die neueste ist ...

Sobald der Auftrag klar ist, können Sie die Zeile:

map { print "Delete: ", join('_', @$_), "\n"; } @batch; 

mit:

map { unlink join('_', @$_); } @batch; 

Damit wird es die Dateien löschen.

Sie können mit dem Sortieralgorithmus im sub spielen, der bestimmt, welche Dateien gelöscht werden sollen. Jetzt vergleicht es die Dateinamensteile von links nach rechts als Strings. Sie können <=> verwenden, um als Nummern anstelle von cmp wo erforderlich zu vergleichen.

+0

Vielen Dank, es funktioniert perfekt. – misterbean2

+1

Kein Problem. Wenn du denkst, dass die Antwort richtig ist, erwäge es zu wählen und es als korrekt zu markieren :-) –