Spezielle Daten verschieben

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.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Hallo zusammen

ich versuche gerade eine Verschiebung von Dateien zu automatisieren, was momentan mit entsprechender Fehlerhäufigkeit manuell durchgeführt wird.

Das verschieben läuft mit untenstehendem Befehl ganz normal. Das Problem ist allerdings, dass ich dazu den gesamten File-Namen erfassen muss, welcher mir aber zuvor nicht bekannt ist. Ich weiss aber, dass in jedem Dateinamen die Kundennummer vorkommt. Entsprechend muss ich untenstehenden Code so verändern, dass mir z.B. anstelle des vollständigen Namen "AA023300408710LFVI" nur die Nummer "408710" heraussucht und danach sämtliche Dokumente mit dieser Nummer in den unter dst festgelegten Ordner ablegt. Dies sind in der Regel mehrere Dokumente, es kann aber auch nur eines oder sogar keines sein. Hat jemand eine Idee, wie ich den folgenden Code anpassen muss?

Code: Alles auswählen

import shutil

src = "C:/Users/Startklar/Desktop/Ausgangsordner"
dst = "C:/Users/Startklar/Desktop/Empfangsordner/Sven"
dst2 = "C:/Users/Startklar/Desktop/Empfangsordner/Gerald"

# Dateien verschieben
shutil.move(src=src + "/AA023300408710LFVI.docx", dst=dst +"/AA023300408710LFVI.docx")
shutil.move(src=src + "/BB023310187105ADIK.docx", dst=dst2 +"/BB023310187105ADIK.docx")
Bin um jede Hilfe sehr dankbar!
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Als erstes mal setzt man Pfadteile nicht mit ``+`` zusammen. Dafür gibt es `pathlin.Path`. Dann wird die Datei beim verschieben gar nicht umbenannt, also muss man den Dateinamen da nicht noch mal dran hängen, das Ziel kann auch einfach ein Verzeichnis sein.

Du brauchst eine Datenstruktur die Kundennummer auf den Unterverzeichnisnamen abbildet und eine Schleife über alle Dateien im Eingangsordner die für jede Datei entscheidet zu welchem Kunden und damit in welches Verzeichnis die Datei gehört. Wobei man da aufpassen sollte, dass das robust bleibt, denn so wie die Dateinamen aussehen und die Kundennummer würde ich mich nicht wundern wenn Du Dateinamen hast bei denen das am Ende nicht eindeutig ist. Da sollte das Programm entsprechend reagieren und nicht einfach den erstbesten Treffer nehmen und die Datei dann womöglich in ein falsches Verzeichnis verschieben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Welche der vielen Zeichen ist denn die Kundennummer? Sind die Dateinamen immer gleich aufgebaut? Woher weißt du die Zuordnung Kundennummer <-> Name?
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Ich weiss nicht immer wo sich die Kundennummer im Dateinamen genau befindet. Ich weiss aber, dass sie immer enthalten ist. Die Zuordnung der Kundennummer zum entsprechenden Namen mache ich mit der dst. Ich bestimme ja im Programm für jede Nummer den entsprechenden Ordner. Sollte eine andere Kombination im Namen gerade zur Kundennummer führen, wäre das reiner Zufall und auch verkraftbar. Das System soll mir nur aus dem gesamten Dateinamen z.B. die Kombination 408710 heraussuchen und es dann in den dafür vorgesehenen Ordner legen. Da die Nummern sehr unterschiedlich sind, kann ich zahlreiche Fehler ausschliessen.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Das mit dem Dateinamen stimmt natürlich. Das File muss nur verschoben werden. Es braucht keinen neuen Dateinamen. Ich denke den Teil kann ich entsprechend weglassen...
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

@ Sirius 3

Die Dateinamen sind leider nicht immer gleich aufgebaut. Die Dateinamen sind nicht immer gleich aufgebaut, die Kundennummer ist allerdings immer dabei und kann auch eindeutig identifiziert werden. Ich brauche einfach einen Befehl der nach der entsprechenden Nummer sucht und diese dann in den vorhergesehenen Ordner verschiebt.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Habe jetzt noch eine andere Variante welche wie folgt aussieht:

Code: Alles auswählen

import os
import re
import shutil

src = "C:/Users/Startklar/Desktop/Ausgangsordner"
filters = [["C:/Users/Startklar/Desktop/Empfangsordner/Sven", r'.*408710*\.docx$'],
           ["C:/Users/Startklar/Desktop/Empfangsordner/Gerald", r'.*10187105*\.docx$']]

for f in os.listdir(src):
    for dst,regexp in filters:
        if re.search(regexp , f):
            shutil.move(src=f, dst=dst)
Bei diesem Code gibt mir das System keine Fehlermeldung, verschoben wird allerdings auch nichts. Die Testdateinamen lauten dabei wie folgt:

- AA023300408710LDVI
- AA023300408710LVFI
- BB0233018105ADIK
- JASDFI0259620ADKF
- SDI59835ADFI58AIL

Was ist hier falsch?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt os benutzt man pathlib.Path.
Ist es Absicht, dass der Name irgendwie xyz40871.docx lautet und vor dem . noch beliebig viele 0en kommen können? Und bei der zweiten Datei beliebig viele 5en?
listdir liefert nur den Dateinamen, und nicht den gesamten Pfad. Reguläre Ausdrücke würde ich hier nicht verwenden.

Code: Alles auswählen

import re
from pathlib import Path
import shutil

BASEPATH = Path("C:/Users/Startklar/Desktop")
SOURCE_PATH = BASEPATH / "Ausgangsordner"
DESTINATION_PATH = BASEPATH / "Empfangsordner"
FILTERS = [
    ("Sven", "408710"),
    ("Gerald", "10187105"),
]

def main():
    for name, customer_number in FILTERS:
        destination = DESTINATION_PATH / name
        for sourcefile in SOURCE_PATH.glob(f"*{customer_number}*.docx"):
            sourcefile.rename(sourcefile, destination)

if __name__ == "__main__":
    main()
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Besten Dank Sirius3

Ja, der Namen wird von einer anderen Gesellschaft erstellt und hat - zumindest für mich - keine Logik. Ich habe Files welche kurz sind und andere welche lang sind. Die Nummer des Kunden ist allerdings immer vorhanden. Generelle Frage, von wo weiss man ob hier os oder pathlib verwendet wird? Ich habe diesbezüglich noch überhaupt keinen Durchblick.

Bei obigem Code erscheint mir jetzt noch folgende Fehlermeldung. Das System spricht davon, dass bei rename zwei Argumente beöntigt werden. Dies ist meiner Meinung nach mit

Code: Alles auswählen

 sourcefile.rename(sourcefile, destination) [\Code] erfüllt. Gemäss Meldung werden im Code allerdings 3 Argumente gefunden....

[Code]
Traceback (most recent call last):
  File "C:\Users\Startklar\Desktop\Move_II.py", line 20, in <module>
    main()
  File "C:\Users\Startklar\Desktop\Move_II.py", line 17, in main
    sourcefile.rename(sourcefile, destination)
TypeError: rename() takes 2 positional arguments but 3 were given
>>> 
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Das ist eine Methode auf `sourcefile` warum denkst Du da *noch mal* `sourcefile` übergeben zu müssen? Das ist ja bereits implizit ein Argument.

Man verwendet für alles `pathlib` für das man es verwenden kann.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Hallo zusammen

Besten Dank für die Unterstützung. Ich bin weiterhin daran, den Code zu interpretieren und ihn so anzupassen, dass er bei mir funktioniert. Dies ist leider nicht ganz einfach mit meinen Kenntnissen...

Hier meine Interpretation:
Der Basepath teilt dem Code mit, wo sich die zu verschiebenden Dateien befinden.
SOURCE_PATH UND DESTINATION_PATH geben die genauen Ordner an, von wo die Dateien nach wohin verschoben werden. Mit Hilfe der Filters kann ich einzeln festhalten, welche Inhalte der Dateinahmen in welche Ordner zu verschieben sind. Ich gehe davon aus, dass ich z.B. beim Ordner "Sven" hinter "408710" weitere Nummern für diesen Ordner ergänzen könnte....oder?

Bei def main(): habe ich dann aber bereits einige Verständnisprobleme. Der erste Teil gibt an, welche Dateien aufgrund des Filters in welchen Ordner im DESTINATION_PATH abgelegt werden müssen. Dann kommt so glaube ich eine Schleife, welche so lange läuft, bis sämtliche in den Filters definierten Vorgaben abgearbeitet wurden. Da die Dateien allerdings nicht umbenannt werden müssen, verstehe ich nicht ganz weshalb ich den sourcefile.rename Befehl benötige?

Zudem habe ich keine Ahnung was der letzte teil mit dem if Code bedeutet? Was wird damit genau ausgedrückt?

Danke und frohe Ostern ;-)
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

und danke, jetzt weiss ich auch für was PATHLIB verwendet wird ;-)
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Bei mir kommt momentan mit folgendem Code die untenstehende Fehlermeldung:

Code: Alles auswählen


import re
from pathlib import Path
import shutil

BASEPATH = Path("C:/Users/Startklar/Desktop")
SOURCE_PATH = BASEPATH / "Ausgangsordner"
DESTINATION_PATH = BASEPATH / "Empfangsordner"
FILTERS = [
    ("Sven", "408710"),
    ("Gerald", "10187105"),
]

def main():
    for name, customer_number in FILTERS:
        destination = DESTINATION_PATH / name
        for sourcefile in SOURCE_PATH.glob(f"*{customer_number}*.docx"):
            sourcefile.rename(DESTINATION_PATH)

if __name__ == "__main__":
   main()

[\Code]

Fehlermeldung:

[Code]

Traceback (most recent call last):
  File "C:\Users\Startklar\Desktop\Move_II.py", line 20, in <module>
    main()
  File "C:\Users\Startklar\Desktop\Move_II.py", line 17, in main
    sourcefile.rename(DESTINATION_PATH)
  File "C:\Users\Startklar\AppData\Local\Programs\Python\Python38\lib\pathlib.py", line 1358, in rename
    self._accessor.rename(self, target)
FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'C:\\Users\\Startklar\\Desktop\\Ausgangsordner\\AA023300408710LDVI.docx' -> 'C:\\Users\\Startklar\\Desktop\\Empfangsordner'
>>> 

[\Code]

Im Ordner "Empfangsordner" befindet sich allerdings überhaupt keine Datei. Ich weiss nicht, weshalb das System dann sagt, dass es bereits existiert....? Stehe richtig auf dem Schlauch.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Der Empfangsordner existiert bereits. Du versuchst die Datei in diesen existierenden Ordnernamen umzubenennen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Danke _blackjack_ brauche ich diese Zeile überhaupt? Ich will ja den Dateinamen nicht umbenennen sondern die Datei nur verschieben?
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Was ist denn Deiner Meinung nach der Unterschied zwischen umbenennen und verschieben (solange man auf dem gleichen Dateisystem bleibt)?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Verstehe, habe jetzt herausgefunden, dass dies scheinbar das gleiche ist. Für mich war umbenennen bisher der Datei einen neuen Namen geben und verschieben etwas von A nach B zu bringen...

Bei sourcefile.rename() muss ich doch innerhalb der Klammer angeben von wo, nach wo die Datei verschoben werden soll oder etwa nicht? Ich meinem Beispiel also von SOURCE_PATH = BASEPATH / "Ausgangsordner" nach DESTINATION_PATH = BASEPATH / "Empfangsordner". Wenn ich aber den Befehl wie folgt schreibe sourcefile.rename(SOURCE_PATH, DESTINATION_PATH) kommt wie erwähnt die Meldung, dass ich drei Argumente geliefert habe. Aber ich habe doch lediglich SOURCE_PATH und DESTINATION_PATH als Argumente, was ist denn das dritte Argument?

Sorry für die dumme Frage, aber ich sehe es nicht.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

wenn ich mit ein Argument entferne und z.B. mit sourcefile.rename(destination) arbeite, was vorher auch definiert wurde, kommt wieder die Meldung, dass die Datei bereits existiert.... Going to be crazy....
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Methoden auf Objekten haben als erstes Argument immer das Objekt selbst. Du musst hier den kompletten Namen angeben den die Datei haben wird, nicht nur den Pfad in dem das enden soll. Sonst ist das doch auch gar nicht eindeutig, denn das würde ja funktionieren wenn es den Zielpfad nicht geben würde, und die Datei hätte dann den Namen des letzten Verzeichnisses in dem Pfad. Also eben nicht Verzeichnis denn wenn es diesen Teil nicht gibt, ist das ja gar kein Verzeichnis.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

also, ich habe jetzt den gesamten Pfad eingefügt:

Code: Alles auswählen

ef main():
    for name, customer_number in FILTERS:
        destination = DESTINATION_PATH / name
        for sourcefile in SOURCE_PATH.glob(f"*{customer_number}*.docx"):
            sourcefile.rename("C:/Users/Startklar/Desktop/Empfangsordner" / name)
Da ja der Code entscheiden muss in welchen Ordner es schlussendlich kommt, aufgrund der Filter, nehme ich an, dass ich am Schluss mit / name arbeiten kann...

mit der Synthax scheint aber weiterhin etwas nicht zu stimmen, da jetzt folgende Meldung kommt:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\Startklar\Desktop\Move_II.py", line 20, in <module>
    main()
  File "C:\Users\Startklar\Desktop\Move_II.py", line 17, in main
    sourcefile.rename("C:/Users/Startklar/Desktop/Empfangsordner" / name)
TypeError: unsupported operand type(s) for /: 'str' and 'str'
>>> 
Antworten