Änderung PDF Namen

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 stehe wieder einmal vor einem für mich unlösbaren Problem.

Ich bin daran ein kleines Programm zum Umbenennen von PDF Dateien zu erstellen. Dabei ist mir einiges gelungen. Ich kann die einzelnen Teile neu zusammensetzen und habe damit ca. 90% des Problems gelöst. Was mich noch fehlt ist der Befehl, wie ich ein Wort durch ein anderes ersetzen kann. Meine Datei lautet zum Beispiel 20200507-Color_red-15289 und ich möchte daraus folgendes machen: 20200507-Farbe_rot-15289.

Wie bekomme ich es hin, dass ich jeweils ein spezielles Wort ändern kann...

Danke
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

str.replace?
Benutzeravatar
__blackjack__
User
Beiträge: 14031
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei wenn „einzelne Teile neu zusammensetzen“ bedeutet, dass die Teile des Namens vorher mal einzeln waren, also beispielsweise "Color" oder "red", dann würde ich das vor dem Zusammensetzen angehen, weil dann weniger schief gehen kann, das ein Wort Teil eines anderen ist.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Danke für die Hinweise.

Der zu ändernde Bestandteil steht allerdings nicht in einem String sondern befindet sich bereits im Namen der PDF Datei. Kann ich da str.replace auch verwenden?

Ich denke auch, dass es mehr Sinn macht zuerst den Namen zu ändern und dann die einzelnen Teile neu zusammenzusetzen.

Danke
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Du kannst den Namen der Datei ja auslesen, das sollte ein String zurückgeben. Darauf kannst du dann str.replace anwenden.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Ich stehe irgendwie total auf dem Schlauch.

Mein Code sieht momentan wie folgt aus:

[img] import os

os.chdir('P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen')

for f in os.listdir():
file_name, file_ext = os.path.splitext(f)
f_date, f_name, f_num, f_can1, f_can2 = file_name.split('_')
str.replace(f_name,'red','rot')

print('{}_{}_{}'.format(f_date, f_name, f_num))
[img]


Er bringt mir die gewünschte Sortierung. Allerdings wird der Name red nicht in rot umgewandelt...
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Du musst den neuen String ja auch an eine Variable binden.

Code: Alles auswählen

old_string = "20200507-Color_red-15289"


new_string = old_string.replace("red", "rot").replace("Color", "Farbe")

print(new_string)
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

@Bebbi: os.chdir sollte man nicht benutzen, weil es globalen Zustand verändert. Benutze einfach die Pfade. Benutze keine Abkürzungen.

Code: Alles auswählen

import os
BESTELL_PATH = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen'
for filename in os.listdir(BESTELL_PATH):
    basename, extension = os.path.splitext(filename)
    date, name, num, can1, can2 = basename.split('_')
    name = name.replace('red', 'rot')
    print('{}_{}_{}'.format(date, name, num))
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Danke Sirius, das funktioniert. Jetzt muss ich zuerst einmal schauen, was Du da alles geschrieben hast:-)
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Also er printet mir das Ergebnis wie gewünscht. Um es auch tatsächlich ausführen zu lassen habe ich nun os.rename(filename, ('{}_{}_{}'.format(date, name, num)) geschrieben. Aber naja.... das scheint ein "unexpected EOF while parsing" zu sein, was auch immer das heisst.
Benutzeravatar
__blackjack__
User
Beiträge: 14031
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Das heisst das die Datei zu ende ist (EOF = „end of file“) aber der Python-Compiler da noch was erwartet. In diesem Fall ist da eine Klammer zu viel.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Danke das macht Sinn.

Auch wenn ich die Klammer wegnehme kommt die Fehlermeldung. Der Bereich nach der Klammer wird dabei rot markiert, es scheint wohl etwas zu fehlen.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Drehe mich ein wenig im Kreis.

Mit untenstehenden Code erhalte ich nun folgende Lösung:

20200507-Color_red-15289.pdf 20200507-Color-rot-15289. Er fügt mir also hinter dem bereits bestehenden Namen die Ergänzung hinzu. Die Idee wäre natürlich, dass einfach nur "red" durch "rot" ersetzt wird. Versuche ich den Code mit os.replace() auszuführen so kommt die Meldung, das er die angegebene Datei "20200507-Color_red-15289.pdf 20200507-Color-rot-15289" nicht finden kann. Dies ist auch logisch, da es diese überhaupt nicht gibt. Er sollte die Datei "20200507-Color_red-15289.pdf" finden und diese in ""20200507-Color_rot-15289.pdf" umschreiben.

Code: Alles auswählen

import os

Umwandlung = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen'
for filename in os.listdir(Umwandlung):
    basename, extension = os.path.splitext(filename)
    date, name, num, can1, can2 = basename.split('_')
    name = name.replace('red, 'rot')
    print(filename, '{}_{}_{}'.format(date, name, num))
[code]

Weiss da jemand weiter?
Benutzeravatar
__blackjack__
User
Beiträge: 14031
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Ja klar, mach einfach das was Du falsch machst richtig. Argumente werden durch Kommas getrennt, nicht durch ``+``. Anders kann ich mir die angebliche Fehlermeldung nicht erklären. Aber wir wissen ja nicht was Du tatsächlich machst. Zeig das doch mal. Zusammen mit der tatsächlichen kompletten Fehlermeldung.

Ich vermute ja eher das Du den Pfad nicht vor den Dateinamen setzt. Und das pdf nicht an den Zielnamen so wie es aussieht.

In neuem Code würde man auch eher `pathlib` anstelle von den Funktionen in `os.path` verwenden.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

@_blackjack_ Danke für Deine Antwort

Ich kann diese allerdings nicht ganz nachvollziehen. Meiner Meinung nach habe ich kein "+" sondern nur Kommas gesetzt oder nicht?

Hier noch einmal die Angaben um aufzuzeigen, was ich genau mache:

Code: Alles auswählen

import os

Umwandlung = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen'
for filename in os.listdir(Umwandlung):
    basename, extension = os.path.splitext(filename)
    date, name, num, can1, can2 = basename.split('_')
    name = name.replace('red, 'rot')
    print(filename, '{}_{}_{}'.format(date, name, num))
[code]

Die Fehlermeldung sieht wie folgt aus:

[Quote]
Traceback (most recent call last):
  File "C:\Users\SM\AppData\Local\Programs\Python\Python38-32\rename_test_1.py", line 8, in <module>
    os.replace(filename, '{}_{}_{}'.format(date, name, num))
FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden: '20200507-Color_red-15289' -> '20200507-Color_rot-15289'
[Quote]

Danke für die Unterstützung
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Datei befindet sich ja auch im Verzeichnis P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen, Du mußt schon den absoluten Pfad angeben.
Damit solche Fehler erst gar nicht passieren können, sollte man nicht die low-level-Funktionen aus os benutzen, sondern pathlib.

Code: Alles auswählen

from pathlib import Path

BESTELL_PATH = Path('P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen')
for filename in BESTELL_PATH.iterdir():
    date, name, num, can1, can2 = filename.stem.split('_')
    name = name.replace('red', 'rot')
    filename.rename(filename.with_name('{}_{}_{}{}'.format(date, name, num, filename.suffix))
PS: Konstanten schreibt man komplett gross.
Das ist nicht genau das, was Du gemacht hast, weil bei dem gezeigten Code gibt es einen SyntaxFehler.
Benutzeravatar
__blackjack__
User
Beiträge: 14031
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Ich bin bei der Vermutung mit dem ``+`` halt davon ausgegangen, dass Du den Fehler korrekt beschrieben hast. Du hast ja geschrieben das die Fehlermeldung sagen würde „das er die angegebene Datei "20200507-Color_red-15289.pdf 20200507-Color-rot-15289" nicht finden kann“. Und so ein Dateiname, der ja aus beiden Namen besteht, könnte halt nur entstehen wenn man die beiden Dateienamen selbst im Code, beispielsweise mit ``+``, zusammenfügt.

Die tatsächliche Fehlermeldung enthält aber *zwei* Dateinamen: den alten, gefolgt von einem ”Pfeil” (``->``) und den neuen: '20200507-Color_red-15289' -> '20200507-Color_rot-15289'. Im Gegensatz zu Deiner Behauptung endet der alte auch gar nicht mit ".pdf", das heisst selbst wenn die PDF-Datei im aktuellen Arbeitsverzeichnis liegen würde, käme genau diese Fehlermeldung.

Der gezeigte Code passt auch nicht zur Fehlermeldung, denn in Zeile 8 steht dort nicht das `os.replace()` aus dem Traceback, sondern ein `print()`-Aufruf.

Du solltest am besten immer den Code zeigen der auch tatsächlich zur Ausnahme geführt hat, und auch die tatsächliche Ausnahme 1:1 kopieren und nicht so ungefähr umschreiben. Sonst müssen wir raten und/oder gehen von falschen Annahmen aus. Beides hilft nicht wirklich beim helfen.

Insgesamt hilft mehr Präzision beim Beschreiben des Problems auch beim Programmieren. Denn während wir menschlichen Helfer noch ein bisschen mitdenken und Lücken durch ein bisschen Nachdenken füllen können, ist so ein Rechner extrem dumm und macht immer nur exakt was man sagt, nie was man eigentlich meinte, solange das nicht auch tatsächlich das ist, was man exakt sagt.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Stimmt, ich bin ziemlich verwirrt. Der Einstieg ins Programmieren ist nicht ohne.... Ich habe am Wochenende versucht das Ganze zu verbessern, wie man sieht erfolglos...

Der Code sieht momentan wie folgt aus:

Code: Alles auswählen

import os

Umwandlung = 'P:/Key Advisors Hauptordner/Empfang/Ordner Bebbi/Bestellungen'
for filename in os.listdir(Umwandlung):
    basename, extension = os.path.splitext(filename)
    date, name, num, can1, can2 = basename.split('_')
    name = name.replace('red', 'rot')
    print(filename, '{}_{}_{}'.format(date, name, num))
[Code]

Die Medlung kommt nun wie folgt (kopiert und sollte nun stimmen):

========= RESTART: C:\Users\SM\AppData\Local\Programs\Python\Python38-32\rename_test_1.py ========
20200430_Color_red_1622244-001_6396015_000000.pdf 20200430_Color_rot_1622244-001
20200430_Color_red_1622287-001_6396012_000000.pdf 20200430_Color_rot_1622287-001
20200430_Color_red_1622564-001_6396014_000000.pdf 20200430_Color_rot_1622564-001
20200430_Color_red_1625009-001_6396011_000000.pdf 20200430_Color_rot_1625009-001
20200430_Color_red_1627843-001_6396013_000000.pdf 20200430_Color_rot_1627843-001
20200430_Color_red_40672361-001_6396016_000000.pdf 20200430_Color_rot_40672361-001
20200430_Color_red_40685701-001_6396020_000000.pdf 20200430_Color_rot_40685701-001
20200430_Color_red_40688541-001_6396018_000000.pdf 20200430_Color_rot_40688541-001
>>>

Die umzuschreibenden Dateien befinden sich alle im unter folgendem Pfad: P:/Key Advisors Hauptordner/Empfang/Ordner Bebbi/Bestellungen => dieser ist doch vollständig oder nicht? Python findet ja die Dateien auch, dies sogar mit dem benutzten os. Muss für pathlib eine andere Bibliothek importiert werden?

Ich bin mir bewusst, dass die Fragen für Euch sehr dumm rüberkommen. Ich habe einfach die Basics noch nicht drin...
Benutzeravatar
__blackjack__
User
Beiträge: 14031
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: `os.listdir()` liefert nur die Namen die in dem Pfad liegen, ohne den Pfad. Das heisst wenn Du einen Namen aus einem ``os.listdir(some_path)`` hast, und die Datei beispielsweise öffnen willst, dann reicht nicht der Name ohne Pfad, sondern man muss dann natürlich auch wieder dafür sorgen, dass `some_path` vor den Namen gesetzt wird.

`pathlib` ist wie `os` ein Modul aus der Standardbibliothek, muss also nicht extra installiert werden. Das hat eine objektorientierte API die es erlaubt in der Regel leichter lesbaren/verstandlichen Code zu schreiben. Zum Beispiel in dem verschiedene Teile des Pfades als Attribute zur Verfügung stehen oder das es Methoden wie `with_name()` gibt. Das kann man auch alles mit den `os`/`os.path`-Funktionen machen, da würde man `stem` aber beispielsweise durch zwei Funktionsaufrufe ausdrücken müssen wo erst Basispfad vom Namen und dann Name von Dateinamenserweiterung getrennt wird.

Da Du anscheinend nur PDF-Dateien verarbeiten willst, würde ich nicht `Path.iterdir()` oder `os.listdir()` verwenden, sondern `Path.glob()` oder das `glob`-Modul. Es passiert immer mal das auf irgendeine Weise andere Dateien in einem Ordner entstehen. Beispielsweise Sicherungskopien von bearbeiteten Dateien, (versteckte) Dateien die Informationen über die Darstellung des Ordners in einem Programm enthalten, Dateien oder Verzeichnisse mit Thumbnails wenn man das Verzeichnis mal mit einem Bildbetrachtungsprogramm oder Dateimanager geöffnet hat der so etwas anlegt, …

Edit: Da Du Informationen aus dem Dateinamen entfernst, würde ich bei so etwas noch einen Test einbauen ob der kürzere Zielname dann eindeutig ist, also ob es die Datei noch nicht gibt. So etwas führt sonst nämlich zu Datenverlusten wenn mehrere Dateien in den gleichen Zielnamen umbenannt werden. Da bleibt am Ende dann ja nur eine übrig.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Bedeutet das, dass ich mein Gerüst nicht gebrauchen kann und dies neu mit iglob aufbauen soll? :o
Antworten