utf-8 codierung

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
pUC19
User
Beiträge: 13
Registriert: Donnerstag 19. September 2019, 14:33

Hallo zusammen.
Ich habe eine allgemeine Frage zum Schreiben von utf-8 codierten Textfiles.

Ich habe vor kurzem ein kleines Script geschrieben, dass automatisch CSV Datei erkennt(Codierung weiß ich nicht), diese bearbeitet und dann wieder als CSV Datei ausgibt (encoding="utf-8"). Dann habe ich von der IT Abteilung die Nachricht bekommen diese CSV Datei doch als txt Datei auszugeben. Ich habe jetzt einfach die CSV Datei in txt Datei umbenannt. Behalten die Dateien ihre Codierung oder muss ich einen Zwischenschritt mit rein schreiben um utf-8 codierten CSV Datei in utf-8 codierten txt Datei umzuwandeln.

Oder anders gefragt. Wie kann ich ermitteln welche Codierung ein File hat?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Umbenennen einer Datei ändert den Inhalt nicht. Also auch nicht die Codierung. Diese kann man bei Dateien gelegentlich erraten. Manchmal klappt das sogar. Eine csv-Datei ist eine Textdatei.
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

Der Zeichensatz/das Encoding bezieht sich darauf, wie die einzelnen Zeichen innerhalb einer Datei, die du in deinem Texteditor siehst, intern abgebildet werden, d.h. wie die zugrundeliegende binäre Repräsentation ist. Daher bringt es, wie kbr schon meinte, nichts, wenn du einfach die Dateiendung änderst. Die Dateiendung an sich hat eigentlich gar keine eigene Bedeutung, sondern allenfalls (unter Windows) eine zugeordnete, die man auch ändern kann. UTF-8 muss man normalerweise nicht gesondert kennzeichnen. Wenn man mit dem Zaunpfahl darauf hinweisen möchte, dass es sich um eine UTF Kodierung handelt, kann man auch bei UTF-8 ein Byte-Order-Mark (BOM) setzen, was aber eigentlich nur bei UTF-16 und UTF-32 sinnvoll ist und bei UTF-8 nicht empfohlen wird.

Den Zeichensatz einer Datei kannst du z.B. mit geeigneten Tools (z.B. chardet, oder 'file' unter Unix) bestimmten. Viele Editoren und IDEs zeigen außerdem das Encoding, das sie meinen festgestellt zu haben (auf eine Weise, die man jeweils in der Doku nachschlagen muss), irgendwo an. Das nachträgliche Feststellen des Encoding ist nicht immer eindeutig möglich, insbesondere nicht, wenn Encodings innerhalb einer Datei gemischt wurden. Daher gibt z.B. chardet eine Wahrscheinlichkeit an.

Das Ändern der Endung von csv nach txt habe ich manchmal bei MS Excel Benutzern gesehen, da es (in manchen Versionen?) anscheinend Probleme beim Einlesen mancher CSV-Dateien mit dieser Endung gibt.

EDIT: Tippfehler.
Zuletzt geändert von nezzcarth am Dienstag 3. März 2020, 20:09, insgesamt 2-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 13107
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nezzcarth: Das Problem bei Excel (ich weiss nicht welche Versionen das betrifft) ist das Excel bei CSV-Dateien keinen Dialog anbietet in dem man so Sachen wie Trennzeichen, Kodierung, Spaltentypen usw. auswählen kann, sondern einfach eine Auswahl trifft, die zudem noch von den Spracheinstellungen des Systems abhängt. Bei *.txt-Dateien kommt so ein Dialog.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

@__blackjack__: Ah, verstehe. (Wäre ja auch schade, wenn der Umgang mit einem Format, das nicht anfällig für Makroviren ist, zu einfach wäre ;) )
pUC19
User
Beiträge: 13
Registriert: Donnerstag 19. September 2019, 14:33

Super Danke für die schnelle Antwort. Klingt logisch.
Um sicher zu gehen, dass die Codierung richtig ist habe ich unten stehend zwei Varianten aufgeschrieben die ich ausprobiert habe.
Die Variante mit chardet habe ich auch schon ausprobiert. Leider funktioniert daß Beispiel was ich gefunden habe nicht.

Import io
With io.open(File,"w", encoding="utf-8")

oder nur:

With open(File,"w", encoding="utf-8")
Benutzeravatar
__blackjack__
User
Beiträge: 13107
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pUC19: `io.open()` macht in Python 3 keinen Sinn mehr, das ist nur noch aus historischen Gründe da. Das Problem ist ja auch nicht eine Textdatei mit Text den man schon hat als UTF-8 zu schreiben. Das Problem ist zu wissen welche Kodierung man beim öffnen der ursprünglichen Datei zum Lesen angeben muss.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
pUC19
User
Beiträge: 13
Registriert: Donnerstag 19. September 2019, 14:33

OK verstehe. Danke
ulipy
User
Beiträge: 83
Registriert: Mittwoch 17. November 2021, 21:42
Wohnort: Ba-Wü

__blackjack__ hat geschrieben: Dienstag 3. März 2020, 20:53 @pUC19: `io.open()` macht in Python 3 keinen Sinn mehr, ..... Das Problem ist zu wissen welche Kodierung man beim öffnen der ursprünglichen Datei zum Lesen angeben muss.
Nachdem ich keine Vortellungsrunde gefunden hatte geht es halt direkt rein hier:

Vielen Dank für den Tip bzw. die Lösung meines Zeichensatz-Problems!

Hatte als Gelegenheitscodierer viel Energie zur Problemsuche im Bereich "Zeichensätze" verwandt, den ich lieber sein lasse, wenns denn geht..

Viele Grüße!
Py::: 1. funktional zuverlässig, 2. Anfänger-lesbar, 3. Py-Konformität
ulipy
User
Beiträge: 83
Registriert: Mittwoch 17. November 2021, 21:42
Wohnort: Ba-Wü

Viellleicht ist der thread noch nicht zu alt, ich hänge das nach einiger Überlegung "wo denn am Besten" noch hier an.

Stunden habe ich bisher darauf verwendet, eine für meinen Zweck akzeptable Lösung zur besten Decodierung von "fremden" Dateien herauszufiltern. Auch nach mindstens zwei Stunden Sucherei und Nachdenken ist mir das leider nicht klar genug..

Es wäre toll, wenn hier jemand helfen könnte!

Das Problem:
Gegeben sind Dateien von Win10 (auf datei umgeleitete dir .. und tree .. Befehle), die sich leider erlauben können, immer noch auf utf-8 zu verzichten..

Solche Dateien werden eingelesen.
(os.walk, scanDir etc als Alternativen sind zumindest ein Stück weit bekannt und können verm. nicht ohne Aufwand oder zusätzliche Module z. B. die Wildcard-Funktionen von dir ersetzen).

Herausgefunden habe ich bis jetzt, dass diese erzeugten Dateien mit cp852, alias 852, alias IBM852, alias OEM 852 etc. ... kodiert sind - zumindest auf meiner Maschine - die Betonung liegt hier auf "zumindest"..

Jetzt sehe ich zwei grundsätzliche Möglichkeiten zum Einlesen, und die sind auch abhängig vom Verhalten von Microsoft..

1) binäres Lesen
geht, ist aber ein Stück weit "zu Fuß"

2) Lesen mit cp852
wäre verm. etwas einfacher und klar durch den verwendeten codec geregelt (noch nicht versucht)

Was würdet ihr vorschlagen zu verwenden, bzw. was wäre ggfs. portabler, sowohl auf die Zeit als auch auf nationale (Win) Installationen bezogen?

Viel zu viel, ich weiß...

Würde mich trotzdem riesig freuen!
Py::: 1. funktional zuverlässig, 2. Anfänger-lesbar, 3. Py-Konformität
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst dich nicht zwangsweise an andere Themen anhaengen - du kannst auch einfach ein eigenes eroeffnen. Da herrscht keine Knappheit hier.

Was deine eigentliche Frage angeht: wuerdest du wie schon angedeutet auf die externen Programme verzichten, wuerde das Problem verschwinden, siehe https://www.python.org/dev/peps/pep-0529/

Dabei ist deine Befuerchtung, es staenden eingebaut in die Python Standardbibliothek keine Moeglichkeiten zur Wildcard-Nutzung zur Verfuegung, unbegruendet. Sowohl das glob Modul als auch modernere pathlib-basierte Varianten stehen zur Verfuegung.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Benutze keine externen Programme, wenn es nicht wirklich nötig ist. Und hier ist es nicht nötig:
pathlib.Path.glob statt dir oder pathlib.Path.rglob statt tree sind die Lösung.
Benutzeravatar
__blackjack__
User
Beiträge: 13107
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ulipy: Wie __deets__ bereits schrieb ist das unter Windows kein Problem wenn man die Dateinamen im Programm selber ermittelt. Wenn Du aber irgendwelche Textdateien hast, die irgendwie zustande gekommen sind und man ausser Windows 10 nichts anderes darüber weiss, dann weiss man halt nicht wie die kodiert sind. Man kann raten, binär einlesen, beim lesen und schreiben mit „surrogates“ arbeiten wenn es nicht wirklich wichtig ist wenn etwas nicht als UTF-8 kodiert werden kann. Kommt halt auch ein bisschen darauf an, was man mit den Daten machen will.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
ulipy
User
Beiträge: 83
Registriert: Mittwoch 17. November 2021, 21:42
Wohnort: Ba-Wü

oh, so schnell umsetzbare Ratschläge für eine gute, stabile Lösung für das Einlesen..

Vielen Dank!

Mangels Erfahrung mit Python (den Wald vor lauter Bäumen nicht sehend..) war ich bisher bei den glob und pathlib Modulen nicht angekommen. Interne Module sind natürlich auch in meiner Denke der beste Weg.

Werd's auf jeden Fall so versuchen!
Py::: 1. funktional zuverlässig, 2. Anfänger-lesbar, 3. Py-Konformität
Michaela81
User
Beiträge: 18
Registriert: Samstag 5. September 2020, 18:47

Sicher nicht die Ideallösung und keine Antwort wie du Dateien korrekt einlesen kannst, aber wenn du beim Einlesen von Dateien die Codierung nicht kennst und notfalls auf einzelne, unbekannte Zeichen verzichten kannst, kannst du folgendes Versuchen
open(DATEINAME, "r", errors='ignore')
Mit dem errors='ignore werden nicht erkannte Bytes eben ignoriert. Kann aber auch dazu führen, das der Text so verstümmelt wird das er unbrauchbar ist.

Black_Jack hat mich freundlicherweise aber heute erst darauf hingewiesen das man zum Lesen von Dateien besser die ``with``-Anweisung verwendet. Ob so etwas auch da möglich ist, habe ich noch nicht geschaut.
ulipy
User
Beiträge: 83
Registriert: Mittwoch 17. November 2021, 21:42
Wohnort: Ba-Wü

Ja, "with" ist sicher besser, es garantiert implizit, dass die file auch wieder geschlossen wird.

Bei dem geschilderten Problem geht es ausschließlich um eine vom BS erstellte Datei. Insofern kann ich wenigstens auf die Stabilität der Ursprungskodierung einigermaßen vertrauen.

Jetzt ziehe ich doch um:
viewtopic.php?f=1&t=53489
Py::: 1. funktional zuverlässig, 2. Anfänger-lesbar, 3. Py-Konformität
Antworten