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

[solved] Pfade+Dateien: aus 2 config-Dateien eine erstellen

dma67

Hacker
Hallo Liebe Community,

ich bin mit meinem Scripting -Latein am Ende (kann nur sehr rudimentäre Sachen)

Folgendes Problem:
Meine Aufgabe besteht darin, ein Icon-Verzeichnis mit Icons neu zu strukturieren und ein neues Icon-Set zusammenzustellen.

Wir haben hier ~ 1500 Icons in der Anwendung. Im ersten Schritt werden nur Pfade angepasst. Dateinamen bleiben unverändert und sind _EINDEUTIG_

Ich habe mittels
Code:
find ressources -type f > FileList_bevor.txt
eine Ausgangsdatei, wo alle Dateinamen und Pfade aufgelistet sind.

Ergebnis
Code:
a/b/c/d/Symbol_Help24x24.png
a/b/c/d/Home/Home_116x16.png
a/b/c/d/e/Konvert16x16.png
a/b/c/d/e/f/JasperViewer16x16.png
...

Dann habe ich die Icons aufgeräumt und habe Folgende Struktur-Datei auch mittels
Code:
find ressources -type f > FileList_after.txt
erzeugt.

Ergebnis
Code:
w/x/y/z/Symbol_Help24x24.png
w/x/y/z/Home/Home_116x16.png
w/x/y/z/q/Konvert16x16.png
w/x/y/z/q/r/JasperViewer16x16.png
...


Frage:
wie muss jetzt ein Script aussehen, damit aus den 2 Dateien FileList_bevor.txt und FileList_after.txt eine KonvertList.txt entsteht, die folgende Struktur hat:

Code:
a/b/c/d/Symbol_Help24x24.png => w/x/y/z/Symbol_Help24x24.png
a/b/c/d/Home/Home_116x16.png => w/x/y/z/Home/Home_116x16.png
a/b/c/d/e/Konvert16x16.png => w/x/y/z/q/Konvert16x16.png
a/b/c/d/e/f/JasperViewer16x16.png => w/x/y/z/q/r/JasperViewer16x16.png
...

Beschreibung: Anhand eines eindeutigen Datei-Namens sollen die Zeilen so gematcht werden, dass dazwischen Zeichen "=>" steht

Hinweis (Mögliche Problemursache):

In der Datei FileList_bevor.txt kann es vorkommen, dass unter verschiedenen Verzeichnissen eine Datei mehrfach denselben Namen haben.

Ergebnis müsste aussehen
Code:
a/b/c/d/e/Konvert16x16.png => w/x/y/z/q/Konvert16x16.png
a/b/c/d/Konvert16x16.png => w/x/y/z/q/Konvert16x16.png


Vielen Dank im voraus!
 

abgdf

Guru
Code:
#!/usr/bin/perl

use warnings;
use strict;

use utf8;
binmode STDOUT, ":utf8";

sub fileToList {
    my $fname = shift;
    my $fh;
    open($fh, "<", $fname) or die "File not found";
    my @a = <$fh>;
    close($fh);
    return @a;
}

my @a = fileToList("FileList_bevor.txt");
my @b = fileToList("FileList_after.txt");

if ($#a != $#b) {
    die "Dateien haben verschiedene Laengen";
}
chomp(@a);
chomp(@b);

my $i;
for ($i = 0; $i <= $#a; $i++) {
    print "$a[$i] => $b[$i]\n";
}
 
OP
dma67

dma67

Hacker
Danke!

Leider gibt es ein Problem
Code:
dma@marekos-c2q-vmsuse:~/dmaVista/vonSuSE/ressources> perl skript1.pl
Dateien haben verschiedene Laengen at skript1.pl line 22.

Es kann nämlich Folgendes vorkommen:
Konvert16x16.png, Konvert.png

Wenn ich
Code:
#if ($#a != $#b) {
#    die "Dateien haben verschiedene Laengen";
#}
das rausnehme, dann tut es, aber kein erwünschtes Ergebnis
Code:
 ressources/entities/BankData/Money_Stack16x16.png => ressources/entities/16x16/DocumentsConfiguration16x16.png 
 ressources/entities/BankData/Money_Stack24x24.png => ressources/entities/16x16/Doublet16x16.png
es sollte aber sein
Code:
 ressources/entities/BankData/Money_Stack16x16.png => ressources/entities/16x16/Money_Stack16x16.png 
 ressources/entities/BankData/Money_Stack24x24.png => ressources/entities/24x24/Money_Stack24x24.png
was nun?
 

abgdf

Guru
Es kann nämlich Folgendes vorkommen:
Konvert16x16.png, Konvert.png
Tja, da hast Du wohl nicht alles erzählt. Das hab' ich mir schon gedacht, deshalb ja die Prüfung, ob die Dateien gleich viele Zeilen haben.

An der Stelle wird's unter Umständen kompliziert. Nach welchem Kriterium sollen solche Zeilen wie oben denn behandelt werden?

Am einfachsten wär's, wenn Du Deine Dateien so anpassen könntest, daß jeder Zeile in Datei 1 genau eine Zeile in Datei 2 zugeordnet wäre.
 
OP
dma67

dma67

Hacker
Erst mal danke für Deine Hilfe.

So wie es aussieht, muss ich zugleich auch die Namen aufräumen (so ist die Anforderung), also nix mit Scripting.. - da ist Benediktiner-Arbeit angesagt.

Das Thema kann man schliessen.
 

spoensche

Moderator
Teammitglied
Sieh dir mal das Tool findimagedupes an. Es vergleicht Images mit einer ca. 98% Genauigkeit. Wenn es gleiche bilder gefunden hat, dann könntest du anhand des Pfades und Dateinamen ermitteln, ob es in der FileList_bevor oder FileList_danach vorhanden ist u. den entsprechenden Eintrag in der neuen Datei erzuegen.
 
A

Anonymous

Gast
spoensche schrieb:

ich vermute mal die Dateien werden nicht verändert, zB nicht vergrößert oder verkleinert oder anders kompimiert und bekommen auch kein anderes Bildformat oder werden auch sonst nicht bearbeitet. Die Dateien als solches bleiben also gleich und sollten vor und hachher zB über die md5sum wieder sauber zusammen gehörig erkannt werden könnten. auch wenn sich die Namen geändert haben. Mit forensischen Bildvergleichen braucht man da wohl nicht wirklich anzufangen. ;)

Wenn sich nur der Path der Dateien ändern und anhand deiner beiden Listen, :???: unter bash wird das schon ein klein wenig komplizierter, wäre aber ein typischer Fall für awk.
Hier und an mindestens noch einer weiteren Stelle hatten wir schon mal ähnlich gelagerte Probleme mit 2 Listen.
Wenn sich die Namen auch noch ändern sollen/dürfen/müssen, dann müssten andere Listen erzeugt werden, nur Path und Name reicht dann nicht mehr aus, zB die oben erwähnte md5sum pro Datei würde helfen.

bei 1500 Dateien würde sich der Aufwand hier ein Script zum auffinden der Änderungen zu erstellen schon lohnen.

robi
 

framp

Moderator
Teammitglied
Der TE hat den Thread auf closed gesetzt. Deshalb die Frage warum es noch weitere Antworten gibt :???:

Die Frage glaube ich beantworten zu können ... sofern die Aufgabenstellung exakt definiert ist kann man das Problem sicherlich schon mit einem Script lösen. Bislang ist es leider offensichtlich noch nicht so klar.

@dariuszmarek: Sofern Du noch an einer Lösung Deines Problems interessiert bist beantworte bitte ob mein Verständnis der Aufgabenstellung und -voraussetzung korrekt ist:

1) Es gibt eine QuellListe von Dateien mit Pfaden und Dateinamen
2) Es gibt eine ZielListe von Dateien mit Pfaden und Dateinamen
3) Ziel ist eine MappingListe zu erstellen wo drin steht wohin eine QuellDatei vom QuellPfad in einen Zielpfad verschoben wurde
4) Gleicher Dateiname aber unterschiedlicher Pfadname bedeutet die Dateien sind identisch
5) Es gibt Dateien wo keine gleichen Dateinamen bei Quelle und Ziel existieren, der Inhalt aber gleich ist
6) Die Anzahl der Quelldateien ist identisch der Anzahl der Zieldateien (Ist violated da abgdfs Script einen Mismatch gefunden hat. Du musst uns sagen warum dieser Mismatch existiert und wie er zu lösen ist)
 
OP
dma67

dma67

Hacker
Hallo Zusammen,

Vielen Dank für Euer Interesse an _meinem_ Problem.
Während ich auf dem Weg nach Hause war, habe ich es mir doch noch überlegt, die Idee mit Scripten aufzugreifen.

Ich bin mir sicher, dass es doch per Script lösbar ist, es gibt eine gewisse Systematik...

Nun zur ausführlichen Schilderung /Antwort auf Fragen:

1) Es gibt eine QuellListe von Dateien mit Pfaden und Dateinamen

Ja. Ich habe ein ausgechecktes Verzeichnis, wo die Struktur mit png-Dateien ziemlich wild ist. Meine Aufgabe ist, ein neues Icon-Set zu erstellen. Bevor ich das aber mache, will ich sicherstellen, dass ich es nur 1x machen muss. Die Kollegen Entwickler haben es doppelt und x-fach eingecheckt.
Beispiel:
/ressources/a/b/c/Tasks.png
/ressources/a/b/Tasks.png
...

Diesen Ist-Stand habe ich mit 'find' erstellt. -> Datei FileList_before.txt
Das heisst, ich habe im Ist-Zustand eine und dieselbe Datei in 2 Unter-Verzeichnissen. Um das Set schneller zu erstellen, will ich die Doppelgänger selbstverständlich "streichen".
Die Sache ist die, dass es Verweise im Quellcode auf die alte Struktur gibt, so dass ich Folgendes zur Verfügung stellen muss:

Beispiel

es war:
[Quelldatei]
/ressources/a/b/c/Tasks.png
/ressources/a/b/Tasks.png

es ist geworden zu:
[Zieldatei]
/ressources/x/y/z/Tasks.png
/ressources/x/y/z/Tasks.png

2) Es gibt eine ZielListe von Dateien mit Pfaden und Dateinamen
Richtig. Diese ist so entstanden, dass ich einfach die png-Icons in eine neue Struktur verschoben habe.(per Drag and Drop). Dann habe ich in der neuen Struktur 'find' ausgeführt
Beispiel:
/ressources/x/y/z/Tasks.png

Beim Aufräumen habe ich z.B festgestellt, dass Tasks.png bereits in der neuen Struktur vorhanden ist. Dann muss sie natürlich nur 1x vorhanden sein.

3) Ziel ist eine MappingListe zu erstellen wo drin steht wohin eine QuellDatei vom QuellPfad in einen Zielpfad verschoben wurde
Richtig. Gewünscht ist eine Mapping-Liste, dieser Art:
/ressources/a/b/c/Tasks.png => /ressources/x/y/z/Tasks.png
/ressources/a/b/Tasks.png => /ressources/x/y/z/Tasks.png

Deswegen muss es so sein, weil wenn es im Quellcode beide Pfade vorhanden sind (also einer hat darauf verwiesen /ressources/a/b/c/Tasks.png und ein anderer auf /ressources/a/b/Tasks.png) soll es in der neuen Struktur NUR 1x vorkommen.

4) Gleicher Dateiname aber unterschiedlicher Pfadname bedeutet die Dateien sind identisch
Richtig.

5) Es gibt Dateien wo keine gleichen Dateinamen bei Quelle und Ziel existieren, der Inhalt aber gleich ist
Jein. Das hängt mit der Frage 6 zusammen.

Genaueres Beispiel:

Ein Icon (vom Aussehen her) hat:
-unterschiedlichen Namen
-unterschiedlichen Pfad
-unterschiedliche Auflösung
ALT:
/ressources/a/b/Tasks.png
/ressources/a/b/Tasks16x16.png
/ressources/a/b/Tasks24x24.png
/ressources/a/b/c/d/Tasks.png

Daraus soll werden: (im ersten Schritt - Namen der Dateien ändern sich nicht, damit ich weiss, was ich austauschen muss)
NEU1:
/ressources/x/y/32x32/Tasks.png
/ressources/x/y/24x24/Tasks24x24.png
/ressources/x/y/16x16/Tasks16x16.png

Wie man sehen kann, -> es geht zu Frage 6



6) Die Anzahl der Quelldateien ist identisch der Anzahl der Zieldateien (Ist violated da abgdfs Script einen Mismatch gefunden hat. Du musst uns sagen warum dieser Mismatch existiert und wie er zu lösen ist)
Eben nicht, In dem Beispiel aus 4 bleiben 3.

In der Zieldatei ist netürlich jedes Icon NUR 1x,
Script müsste also folgendes machen:

1. Zeile für Zeile in der alten Struktur (Quelle-Datei] nach dem Dateinamen Prüfen

/ressources/a/b/---->Tasks.png
/ressources/a/b/--->Tasks16x16.png
/ressources/a/b/--->Tasks24x24.png
/ressources/a/b/c/d/--->Tasks.png

2. Findet sich in der Zieldatei eine Zeile mit dem Dateinamen 'Tasks' (zur Erinnerung, sie wird nur 1x in der Zieldatei vorkommen)
also das
/ressources/x/y/32x32/Tasks.png

3. dann soll die ganze Zeile als Mapping hinzugefügt werden
/ressources/a/b/Tasks.png => /ressources/x/y/32x32/Tasks.png
/ressources/a/b/c/d/Tasks.png => /ressources/x/y/32x32/Tasks.png

findet er Tasks16x16.png dann
/ressources/a/b/Tasks16x16.png => /ressources/x/y/16x16/Tasks16x16.png

findet er Tasks24x24.png dann
/ressources/a/b/Tasks24x24.png => /ressources/x/y/24x24/Tasks24x24.png

etc....

Wenn ich die Mapping-Datei habe, dann ist der 2-Schritt notwendig. Ich habe bereits ein Set von Icons in einer grösseren Auflösung zusammengestellt. Ich möchte dann den Dateinamen auf der rechten Seite des Mappings die Nummern wegnehmen. Es soll dann (vielleicht von Hand) so etwas werden:

/ressources/a/b/Tasks.png => /ressources/x/y/32x32/Tasks.png
/ressources/a/b/c/d/Tasks.png => /ressources/x/y/32x32/Tasks.png

/ressources/a/b/Tasks16x16.png => /ressources/x/y/16x16/Tasks.png
/ressources/a/b/Tasks24x24.png => /ressources/x/y/24x24/Tasks.png

Dann ist Mapping perfekt.

4. Als Nächstes sollen die Dateinamen in der neuen Verzeichnis-Struktur (ohne Zahlen 16x16, 24x24, 24, 16 ) geändert werden. (vielleicht per Script)

5. Aus dem "neuen" Icon-Set sollen die Icons im Verzeichnis /ressources/x/y/32x32/ ersetzt werden.

6. Da nun alle Auflösungen gleich heißen und nur der Pfad unterschiedlich ist, lassen sich die 32x32 (vielleicht per Script) herunterskalieren und im jeweiligen Verzeichnis speichern.

Warum das Ganze?

Ich möchte aus dem jetzigen Chaos der Pfade und der Namen (ca 1800 Stück) die Struktur so machen, dass ich immer ein Set bestehend aus ca 300Stück benötige, in die Grösste Auflösung (32x32) packe und (per Script) herunterskalieren lasse, und zwar so, dass ich NUR die physikalischen Dateien austausche und KEINE config-Dateien oder Quellcode ändere (halt so wie Linux Icons ;-) Icons im Verzeichnis austauschen, Verzeichnis austauschen -> fertig.

So der Plan ;-)
Ich zähle auf Eure Hilfe und Danke im Voraus für jede Unterstützung!

P.S. Ich kann es nicht oft genug sagen: TOLLES Forum hier!!!
 

framp

Moderator
Teammitglied
Der folgenden Code sollte Deine gewünschte Liste erstellen. ACHTUNG: Alle Einrückungen müssen erhalten bleiben. Ansonsten bekommst Du Laufzeitfehler.
Code:
#!/usr/bin/python
#-*- coding: utf-8 -*-

import sys
import os

def populateDict(fileName):
    oldDictionary={}
    oldFile=open(fileName,'r')
    print " === %s === " % (fileName)
    for oldFileName in oldFile:         # prozessiere file
        (dirName,baseName) = os.path.split(oldFileName.strip()) # splitte in pfad und filename
        if baseName in oldDictionary:                   # filename schon bekannt
            if not dirName in oldDictionary[baseName]:  # pfad in liste aufnehmen wenn nicht schon da
                oldDictionary[baseName].append(dirName)
        else:
            oldDictionary[baseName]=[dirName]           # filename ist neu
    oldFile.close()
    for (k,v) in oldDictionary.items():                 # ausgabe des ergebnisses
        print "--> %s: %s" % (k,v)
    print 
    return oldDictionary

def main(argv):
    
    if len(sys.argv) < 2:
        print "Usage: " + os.path.basename(sys.argv[0]) + " oldFile newFile"
        sys.exit(-1)
                
    if not os.path.exists(sys.argv[1]):
        print "??? %s not found" % (sys.argv[1])
        sys.exit(-1)
         
    if not os.path.exists(sys.argv[2]):
        print "??? %s not found" % (sys.argv[2])
        sys.exit(-1)         

    oldDictionary=populateDict(sys.argv[1])     # lies alt                         
    newDictionary=populateDict(sys.argv[2])     # lies nwu    
    
    for (baseName,directories) in oldDictionary.items():    # gehe über alle alten filenamen
        for oldDirectory in directories:
            if baseName in newDictionary:
                newDirectory=newDictionary[baseName]            # das ist der neue pfad
                print "%s => %s" % (oldDirectory+"/"+baseName, newDirectory[0]+"/"+baseName)
            else:
                print "??? Error: %s not found in NEW but used in OLD" % (baseName)
                                    
if __name__ == '__main__':
    main(sys.argv)
Die folgende Dinge macht das Script nicht da mir nicht klar ist was Du genau meinst.
Wenn ich die Mapping-Datei habe, dann ist der 2-Schritt notwendig. Ich habe bereits ein Set von Icons in einer grösseren Auflösung zusammengestellt. Ich möchte dann den Dateinamen auf der rechten Seite des Mappings die Nummern wegnehmen. Es soll dann (vielleicht von Hand) so etwas werden:

/ressources/a/b/Tasks.png => /ressources/x/y/32x32/Tasks.png
/ressources/a/b/c/d/Tasks.png => /ressources/x/y/32x32/Tasks.png

/ressources/a/b/Tasks16x16.png => /ressources/x/y/16x16/Tasks.png
/ressources/a/b/Tasks24x24.png => /ressources/x/y/24x24/Tasks.png
Welche Nummern sollen weg?
4. Als Nächstes sollen die Dateinamen in der neuen Verzeichnis-Struktur (ohne Zahlen 16x16, 24x24, 24, 16 ) geändert werden. (vielleicht per Script)
Beispiel?
5. Aus dem "neuen" Icon-Set sollen die Icons im Verzeichnis /ressources/x/y/32x32/ ersetzt werden.
Beispiel ?
 
OP
dma67

dma67

Hacker
@framp
HERZLICHEN D A N K

DU hast mir jede Menge Arbeit erspart.
Nun habe ich meine ausersehnte Mapping-Datei mit ~1500 Mappings und das in einer Sekunde....

Frage 1
Welche Nummern sollen weg?
Muss und will ich von Hand machen, denn ich will auch die Namen der Icons passender wählen.
IST-Beispiel
Code:
ressources/swingclient/Toolbar_Menubar/ActivityReport/ActivityReport16x16.png => ressources/swingclient/icons/16x16/ActivityReport16x16.png
ressources/swingclient/Toolbar_Menubar/ActivityReport/ActivityReport24x24.png => ressources/swingclient/icons/24x24/ActivityReport24x24.png

SOLL-Beispiel
Code:
ressources/swingclient/Toolbar_Menubar/ActivityReport/ActivityReport16x16.png => ressources/swingclient/icons/16x16/ShowActivityReport.png
ressources/swingclient/Toolbar_Menubar/ActivityReport/ActivityReport24x24.png => ressources/swingclient/icons/24x24/ShowActivityReport.png

Fazit: Da die Icons vorher in EINEM ordner waren, mussten sie anders heißen. Da sie jetzt in anderen Foldern liegen (je nach Auflösung), können sie nun in der neuen Struktur gleich heißen.

Da ich aber unter Umständen das aussagefähiger machen will (ActivityReport.png -> ShowActivityReport.png), so muss ich zuerst überlegen, was ich da ändern will. Dafür habe ich ja die Mapping-Datei, wo ich zuerst den neuen Namen ändere und dann in dem Verzeichnis diese physikalische png-Datei umbenenne. Aber die Bendediktiner-Arbeit mit dem Mapping ist ja schon getan.

Nochmals: Dankeschön framp.

diesmal [closed]
 
Oben