Mein kleines Projekt

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Hi,

ich bin ein ziemlicher Neuling was programmieren angeht, möchte mir aber so schnell wie möglich ein Script zusammen basteln.
Von der gewünschten Funktion her sieht es wie folgt aus.

1. Das Script muss auf einer Website nach der aktuellsten .tar Datei suchen und herunterladen
2. Aus dem .tar Archiv müssen bestimmte Dateien entpackt und gespeichert werden
3. Diese Dateien müssen an einen anderen Ort kopiert werden
Info: Der Name des Archivs ändert sich täglich und die gewünschten Dateien haben unterschiedliche Typen.

Hört sich für die Profis natürlich alles andere als schwer an :p

Punkt 1 habe ich schon hinbekommen.

Bei Punkt 2 schaffe ich es eben nicht genau diese Dateien zu entpacken. Ich möchte aus Speicherplatzgründen auch nicht das ganze Archiv entpacken.
Im Archiv sind verschiedenste Ordner und Dateien enthalten.

Bei Punkt 3 gleiche Problem. Wenn ich bei Punkt 2 dann doch alle Dateien in einen Ordner entpacke, schaffe ich es nicht nur die gewünschten Dateien zu kopieren.

Vielleicht könnt ihr Licht ins Dunkle bringen.
BlackJack

@python7: Ad 2) Wie man nur bestimmte Dateien filtern kann steht in der Dokumentation zum `tarfile`-Modul. An der Stelle würde ich wahrscheinlich auch versuchen ob man entweder sinnvoll die Namensinformation im `TarInfo`-Objekt vor dem entpacken anpassen kann um die Datei gleich gezielt woanders hin zu schreiben. Ansonsten müsste man sich ein Dateiobjekt für die entsprechenden „member” geben lassen, die Zieldatei öffnen und mit der passenden Funktion aus dem `shutil`-Modul den Inhalt kopieren. Ob man dann am Ende noch selber die Metadaten wie Rechne und Besitzer anpassen möchte kann/muss man auch entscheiden.
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Ich dachte, dass es so funktionieren würde. Aber er findet die Datei nicht.

Code: Alles auswählen

import tarfile

tar = tarfile.open ('Archiv.tar', 'r')
for name in ['A', 'A.xyz', 'B', 'B.xyz']:
    tar.extract(name, 'tmp')
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

KeyError: "filename 'A' not found"

Also ich kann mir vorstellen wieso.....
In dem Archiv sind ja wie gesagt mehrerer Ordner und Dateien.
Die gesuchte Datei(en) liegen z.B. in Folder1\Folder2\Folder3\File und er sucht momentan wohl nur direkt im root von dem Archiv. Verstehe nur nicht so ganz wie ich das ganze Archiv nach den Dateien durchsuche und dann eben nur die gewünschten Dateien entpacken kann.
Zuletzt geändert von python7 am Sonntag 21. Dezember 2014, 23:39, insgesamt 1-mal geändert.
BlackJack

@python7: Gibt es in dem Archiv denn eine Datei mit diesem Namen?
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Hat noch jemand einen Hinweis für mich?
BlackJack

@python7: Ein Hinweis ist die Dokumentation des Moduls. Und bezüglich Verzeichnissen und Dateinamen: Ein Archiv hat kein ”root”, jeder Eintrag hat den kompletten Pfad gespeichert und auch nur den kann man direkt angeben. Die Pfade müssen auch nicht ein gemeinsames Wurzelverzeichnis haben, die können tatsächlich komplett beliebig sein. Wenn man Dateien suchen möchte dann muss man sich alle gespeicherten Pfade im Archiv anschauen und dann den Pfad analysieren ob man die Datei extrahieren möchte oder nicht.
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Wie schon geschrieben, bin ich in diesem Thema nicht so bewandert.
Ich weiß, dass ich mit getmembers die Dateien bekomme. Wenn ich den kompletten Pfad angebe, kann ich diese auch entpacken....logisch.
Wie kann ich denn eine Datei entpacken wenn sich der erste Teil immer ändert.

Um es noch mal zu verdeutlichen.
IchbinderTeildersichimmerändert\IchbineinOrdnerundbinimmergleich\IchbindieDatei
Dachte in Python kann ich auch einfach mit Wildcards arbeiten, aber das probierte haut nicht hin.

Dachte an eine art
*\IchbineinOrdnerundbinimmergleich\IchbindieDatei
oder
...\IchbineinOrdnerundbinimmergleich\IchbindieDatei

Wie auch immer.
Das Script funktioniert nun komplett wie ich es haben möchte. Allerdings fehlt mir einfach nur noch dieser eine etwas schönere part mit eben nicht alles entpacken, sondern nur die gewünschten Dateien.
BlackJack

@python7: Die Dateinamen/Pfade sind Zeichenketten und damit kann man eine ganze Menge machen. Tests, Aufteilen, Teilzeichenketten extrahieren, und so weiter. Um mit Wildcards zu testen kann man das `fnmatch`-Modul verwenden, oder die grossen Geschütze auffahren: das `re`-Modul.
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Ok, ich hab mir jetzt etwas gebaut, dass nur diese vier Dateien entpackt werden. Vermutlich nicht schön, aber es funktioniert.
Nun werden diese Dateien aber mit der ganzen Struktur entpackt. Gibt es da eine möglichkeit diese wegzulassen und direkt in das angegeben Verzeichnis zu entpacken?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Zeig mal deinen Code, es lässt sich leichter mit konkreten Programmen arbeiten.
Das Leben ist wie ein Tennisball.
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Code: Alles auswählen

bname = os.path.splitext('Archiv.tar')[0]
omember = [bname+'/Ordner/DateiA', bname+'/Ordner/DateiA.xyz', bname+'/Ordner/DateiB', bname+'/Ordner/DateiB.xyz']
tar = tarfile.open('Archiv.tar', 'r')
for name in omember:
    tar.extract(name,'tmp')
tar.close()
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@python7: sollen wir jetzt für Dich die Dokumentation nach der passenden Methode (extractfile) durchlesen?

Wenn es einen konstanten und einen variablen Anteil gibt, dann setzt man die beiden am besten nicht schon beim definieren des konstanten Anteils fest, sondern in einem seperaten Schritt:

Code: Alles auswählen

FILES_TO_EXTRACT = ['Ordner/DateiA', 'Ordner/DateiA.xyz', 'Ordner/DateiB', 'Ordner/DateiB.xyz']
tarfilename = 'Archiv.tar'
base = os.path.splitext(tarfilename)[0]
with tarfile.open(tarfilename, 'r') as tar:
    for filename in FILES_TO_EXTRACT:
        tar.extract(os.path.join(base, filename), 'tmp')
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du gehst das Problem von der falschen Seite aus an. Wenn du in einem Archiv suchen möchtest, dann musst du als erstes die Namen aller darin gespeicherten Dateien sammeln. Schau dazu mal in die Dokumentation des tarfile-Moduls, da wirst du sicher schnell fündig. Anschließend iterierst du über alle Namen und prüfst, ob diese deinem Suchkriterium entsprechen. Wenn du dann eine Datei gefunden hast, dann hast du dazu den vollständigen Pfad und kannst sie entpacken.
Das Leben ist wie ein Tennisball.
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Sirius3 hat geschrieben:@python7: sollen wir jetzt für Dich die Dokumentation nach der passenden Methode (extractfile) durchlesen?

Wenn es einen konstanten und einen variablen Anteil gibt, dann setzt man die beiden am besten nicht schon beim definieren des konstanten Anteils fest, sondern in einem seperaten Schritt:
Naja so wie jetzt ein Codebeispiel oder Snippet habe ich mir schon erhofft, ja. Wie schon im Eingangspost erwähnt habe ich mit dieser Materie so gut wie nichts zu tun, deshalb habe ich auch das Wort 'basteln' verwendet.
Vielen Dank für dieses Beispiel und den Hinweis, allerdings bläst er mir diesen Fehler aus.

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Python27/Scripts/test_extract2.py", line 8, in <module>
    tar.extract(os.path.join(base, filename), 'tmp')
  File "C:\Python27\lib\tarfile.py", line 2075, in extract
    tarinfo = self.getmember(member)
  File "C:\Python27\lib\tarfile.py", line 1796, in getmember
    raise KeyError("filename %r not found" % name)
KeyError: "filename 'Archiv\\\\Ordner/DateiA' not found"
python7
User
Beiträge: 9
Registriert: Sonntag 21. Dezember 2014, 22:06

Ok, habs mit einem +'/' an base gefixt. Aber wie schon erwähnt, wäre es super, wenn ich das ganze direkt in 'tmp' bekommen würde. Ohne eben die ganze Struktur.
Ich probier natürlich permanent weiter :p
Antworten