• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst]Bash script zum Vergleichen von Verzeichnissen

saigo

Newbie
Hallo,
ich habe hier gerade 2 Verzeichnisse vorliegen, diese beinhalten die selben Bilder einmal als JPG und im anderen als RAW
Die JPG Bilder habe ich durchgesehen und einige gelöscht. Gibt es eine Möglichkeit die Verzeichnisse so zu vergleichen das in dem mit den RAW Dateien die gelöscht werden zu denen es keine Entsprechung mehr bei den JPG gibt? :???:
die Bilder heißen gleich nur die Endung ist halt unterschiedlich. ich möchte ungern von Hand alles abgleichen

Viele Grüße, Saigo
 
A

Anonymous

Gast
geht schon, nur ohne die Gegebenheiten genau zu kennen ???, hier muss man wohl ein bisschen Scripten
mal so aus dem Handgelenk ohne das ich das jetzt testen könnte. (ungetestet und ohne Garantie)

Angenommen, das JPG Verzeichnis nennt sich "jpeg_dir" und das Raw Verzeichnis "raw_dir" und die Extensionen der Dateien sind ".raw" und ".jpg" und die Dateien liegen alle beide flach (also nicht in weiteren Unterverzeichnissen) vor,

Code:
for DATEI in raw_dir/*.raw
   do
   NAME=$(basename  "$DATEI"  ".raw")
   if [ ! -f jpeg_dir/${NAME}.jpg ]
      then 
        echo $DATEI
   fi 
done

Ausgabe sollte sein, alle RAW-Dateien für die es keine JPG File zu finden gibt.

Überprüfen ob das so ist, wenn ja, dann könnte man das echo durch ein rm austauschen

robi
 

abgdf

Guru
Auch nicht so schön:
Code:
#!/usr/bin/perl

use warnings;
use strict;

my $jd = "/home/user/jpgs";
my $rd = "/home/user/raws";

my @a = &getfiles($jd, "jpg");
my @b = &getfiles($rd, "raw");

foreach my $i (@b) {
    my $name = $i;
    $name =~ s/\.raw$//i;
    my $x = 0;
    foreach my $u (@a) {
        my $n2 = $u;
        $n2 =~ s/\.jpg$//i;
        if ($name eq $n2) {
            $x = 1;
            last;
        }
    }
    if ($x == 0) {
        print "To delete: '$rd/$i'.\n";
        # unlink "$rd/$i";
    }
}

sub getfiles {
    my $dir = shift;
    my $suffix = shift;
    my $filename;
    my @files = (); 
    opendir (DIR, $dir) || die "Error opening directory '$dir',";
    while(($filename = readdir(DIR))){
        if ($filename ne "." &&
            $filename ne ".." &&
            $filename =~ /\.$suffix$/i) {
            push(@files, "$filename");
        }   
    }   
    return @files;
}
 
OP
S

saigo

Newbie
Hallo,
vielen Dank, das Shellscript schreibt leider nur alle Dateien auf RAW raus ohne abgleich.
Bei dem Perl Script scheint der vergleich zu stimmen aber da weiß ich nicht wie ich es einstelle das er die auch löscht
Dankbare Grüße, Saigo
 

framp

Moderator
Teammitglied
Der Vollstaendigkeit halber noch eine Version in Python :roll: :
Code:
#!/usr/bin/python
import os     
jpgPath = '/home/framp/test/jpg'
rawPath = '/home/framp/test/raw'
rawFiles = os.listdir(rawPath)
for rawFile in rawFiles:
    baseName = os.path.splitext(rawFile)[0]
    jpgFile = jpgPath + '/' + baseName + '.jpg'
    if not os.path.isfile(jpgFile):
        print "Deleting " + rawFile
#        os.remove(rawFile)
 
OP
S

saigo

Newbie
Das python Script wirft leider folgendes aus:
Code:
python verg.py
  File "verg.py", line 8
    jpgFile=jpgPath+'/'+baseName+'.jpg'
    ^
IndentationError: unexpected indent
 

framp

Moderator
Teammitglied
Du must den gesamten Programtext 1:1 kopieren (also den gesamten Teil in Code Tags). Python hat die Eigenart, dass Bloecke nicht mit Klammern { und } wie in anderen Programmiersprachen gekennzeichnet werden, sondern mit Einrueckungen. Wenn diese nicht fuer alle Zeilen in einem Block uebereinstimmen bekommst Du diese Fehlermeldung.
 

abgdf

Guru
saigo schrieb:
Bei dem Perl Script scheint der vergleich zu stimmen aber da weiß ich nicht wie ich es einstelle das er die auch löscht
Also, erstmal war da noch ein Fehler in meinem Perl-Skript, den ich oben noch verbessert habe (war selbst einmal mit den Verzeichnissen durcheinandergeraten).
Wenn es auch wirklich löschen soll (wollte es erstmal "nicht scharf" posten), mußt Du vor der Zeile
Code:
# unlink "$rd/$i";
einfach das "#"-Zeichen entfernen.
Aber probier vorher bitte noch einmal aus, ob auch wirklich die richtigen Dateien angezeigt werden. Es schadet auch nicht, vorher lieber noch ein Backup der Dateien zu machen. ;)

Gruß

PS: @framp: War klar, daß Du das mit den Einrückungen erst noch erklären mußtest. Das ist der Nachteil, Python scheint deswegen nicht so gut für Forenpostings geeignet zu sein. Die Semikola bei Perl sind umständlich, aber dafür kann man den Code überall 'reinschmeißen, Postings, Emails, usw. ... :D
 

framp

Moderator
Teammitglied
abgdf schrieb:
...PS: @framp: War klar, daß Du das mit den Einrückungen erst noch erklären mußtest. Das ist der Nachteil, Python scheint deswegen nicht so gut für Forenpostings geeignet zu sein. Die Semikola bei Perl sind umständlich, aber dafür kann man den Code überall 'reinschmeißen, Postings, Emails, usw. ... :D
Das kommt darauf an wie genau der Code kopiert wird. I.d.R. gibt es da keine Probleme. Muss zugeben, dass mir diese Zwangseinrückungen zu Anfang auch suspect waren. Speziell da sie immer genau passen müssen und kein kleines Spacechen zu viel oder zu wenig vorkommen darf. Mittlerweile finde ich es aber gut nicht mehr diese aus rein syntaktischen Gründen notwendigen Klammerkaskaden, die der Leserlichkeit nicht unbedingt dienen,
Code:
        }
    }
    if ($x == 0) {
        print "To delete: '$rd/$i'.\n";
        # unlink "$rd/$i";
    }
}
schreiben und lesen zu müssen (Gilt für diverse Sprachen wie Perl, C, C++, Java, usw) :D
 
OP
S

saigo

Newbie
Ok jetzt lief das perl-skript super.
Also allen vielen Dank.
Python war leider zum Kopieren wohl leider wirklich nicht so doll.

Dankbare Grüße, Saigo

P.S. Natürlich immer alles mit Backup gemacht ;)
 

abgdf

Guru
@Saigo: Freut mich, daß es jetzt läuft.

Python ist eigentlich eine tolle Sprache. Das mit den Einrückungen muß man halt am Anfang lernen, aber das ist schon in Ordnung, weil man damit dann eben viel weniger schreiben muß, wie framp schon richtig gesagt hat.
Ist jetzt auch kein schlimmer Zwang, weil man den Code-Block ja irgendwie kenntlich machen muß, hat also seine Berechtigung. Ehrlich gesagt hätte ich das auch gern für Perl, es gibt da dieses Modul, aber das ist in der Praxis leider nicht wirklich brauchbar. Würde mich freuen, wenn das als Option in Perl6 kommen würde, aber es sieht leider nicht so aus, die Perl-Leute scheinen da einigermaßen stur zu sein.
Ich hatte das oben nur angemerkt, weil ich fast jedesmal, wenn ich mal Python-Code (außerhalb des Python-Forums) poste, das mit den Einrückungen erklären muß. Erstmal kommt fast immer 'Dein Code läuft nicht, "indentation error"'. Das ist für die Leute, die gern schnell ein funktionierendes Skript hätten, natürlich erstmal frustrierend. :D
 

framp

Moderator
Teammitglied
saigo schrieb:
...Python war leider zum Kopieren wohl leider wirklich nicht so doll...
Es wuerde mich interessieren wie Du kopiert hast und warum Du das Problem bekommen hast. Ich habe zum Testen
1) den Text im CodeBlock selektiert
2) per copy ins Clipboard geholt
3) einen Editor geoeffnet
4) per paste den Code in den Editor kopiert
5) den Editor geschlossen
6) chmod +x auf die Datei
7) Aufruf und es funktioniert praechtig ;)
 

framp

Moderator
Teammitglied
abgdf schrieb:
...Ich hatte das oben nur angemerkt, weil ich fast jedesmal, wenn ich mal Python-Code (außerhalb des Python-Forums) poste, das mit den Einrückungen erklären muß. Erstmal kommt fast immer 'Dein Code läuft nicht, "indentation error"'. Das ist für die Leute, die gern schnell ein funktionierendes Skript hätten, natürlich erstmal frustrierend... :D
Ein entsprechenden Satz in Komentar am Anfang in den Code wuerde das Problem vielleicht loesen.
 
Oben