2016-06-20 15 views
0

Ich habe erfolgreich Datendateien analysiert, die ich mit einem einfachen Python-Skript, das ich geschrieben habe, erhalte. Die Dateien, die ich bekommen sind wie folgt aus:Python 3.5.1 Mischzeilencode-Datei UTF-8 und UTF-16

datei.txt, ~ 50 Spalten von Daten, x 1000s Reihen

abcd1,1234a,efgh1,5678a,ijkl1 ...etc 
abcd2,1234b,efgh2,5678b,ijkl2 ...etc 
... 

Unfortunatly, manchmal einige der Linien UTF-16 Symbole enthalten, und wie folgt aussehen

abcd1,12341,efgh1,UTF-16 symbols here,ijkl1 ...etc 
abcd2,1234b,efgh2,5678b,ijkl2 ...etc 
... 

ich in der Lage gewesen, die "Latin-1" Codierung für Befehle in meinem Skript zu implementieren wie:

open('file fixed.txt', 'w', encoding="latin-1").writelines([line for line in open('file.txt', 'r', encoding="latin-1"]) 

Mein Problem liegt in Code wie:

for line in fileinput.Fileinput('file fixed.txt', inplace=1): 
    line = line.replace(":",",") 
    print (line, ",") 

Ich bin nicht in der Lage, vorbei an den Codierungsfehler für den letzten Befehl zu erhalten. Ich habe versucht, die Codierung der Durchsetzung:

# -*- coding: latin-1 -*- 

Am oberen Rand des Dokuments sowie vor dem zuletzt genannten Befehl (Suchen und Ersetzen). Wie kann ich gemischte codierte Dateien zur Verarbeitung für den obigen Befehl erhalten? Ich möchte die UTF-16 (Unicode) -Symbole so beibehalten, wie sie in der neuen Datei erscheinen. Danke im Voraus.

EDIT: Dank Alexis konnte ich feststellen, dass Filinput nicht für die Einstellung einer anderen Kodierungsmethode funktionieren würde. Ich habe das Folgende benutzt, um mein Problem zu lösen.

f = open(filein,'r', encoding="latin-1") 
filedata = f.read() 
f.close() 

newdata = filedata.replace("old data","new data") 

f = open(fileout,'w', encoding="latin-1") 
f.write(newdata) 
f.close() 
+2

Es macht keinen Sinn, eine Datei zu haben, die Daten in mehreren verschiedenen Kodierungen enthält. Ist deine Datei * all * in UTF-8? Wenn nicht, müssen Sie wahrscheinlich etwas "operieren", um alles in eine einzige Kodierung zu bringen. Beachten Sie auch, dass es kein UTF-16-Symbol gibt. Sie können Unicode-Symbole mit einer beliebigen Unicode-Codierung codieren. – BrenBarn

+5

(Übrigens, das '# - * - Coding'-Ding ist hier ein Ablenkungsmanöver. Das spezifiziert nur die Kodierung Ihrer Python-Quelldatei; es beeinflusst nicht, was mit eingelesenen Datendateien passiert.) – BrenBarn

+0

Also was machen diese "UTF-16-Symbole" sehen aus? Wie hast du herausgefunden, dass das UTF-16 war? – roeland

Antwort

1

Sie können sagen, fileinput, wie Sie Ihre Dateien öffnen. Wie the documentation sagt:

können Sie steuern, wie Dateien, indem eine Öffnung Haken über den openhook Parameter() oder FileInput-(), um fileinput.input geöffnet werden. Der Hook muss eine Funktion sein, die zwei Argumente, Dateiname und Modus, akzeptiert und ein entsprechend geöffnetes dateiähnliches Objekt zurückgibt. Zwei nützliche Haken sind bereits von diesem Modul zur Verfügung gestellt.

So würden Sie es wie folgt tun:

def open_utf16(name, m): 
    return open(name, m, encoding="utf-16") 

for line in fileinput.FileInput("file fixed.txt", openhook=open_utf16): 
    ... 

I "utf-16" als Codierung verwenden, da diese Codierung Ihre Datei ist, nicht "latin-1". 8-Bit-Codierungen haben keine Fehlerprüfung, so dass Latin1 die Bytes liest, ohne zu bemerken, dass etwas falsch ist, aber Sie haben wahrscheinlich Probleme auf der ganzen Linie. Wenn dies zu Fehlern führt, befindet sich Ihre Datei nicht in utf-16.

+0

Alexis, deine Lösung funktioniert für mich, außer du kannst sie nicht verwenden und den Haken öffnen. Ich brauche die Dateieingabe, um entweder zu schreiben oder in eine andere Datei zu speichern. Danke noch einmal. – james

+0

Hmm, ich würde mit einer anderen Datei schreiben, wenn ich es wäre. Aber musst du 'fileinput' wirklich benutzen? Du schubst es irgendwie hart. Wenn Sie Ihre eigene Dateiverwaltung machen, ist das Leben viel einfacher. – alexis

+0

@james Wenn dies für Sie funktioniert, würde ich genau überprüfen, was in Ihren Dateien ist. Das Öffnen einer Datei mit gemischten Kodierungen als utf-16 kann zu sehr unerwarteten Ergebnissen führen. Aber wenn Sie es auf diese Weise richtig lesen können, ist vielleicht alles einfach utf-16. – viraptor

0

Wenn Ihre Datei eine gemischte Codierung hat, müssen Sie sie als Binärdatei lesen und dann je nach Bedarf verschiedene Teile dekodieren oder das Ganze stattdessen als Binärdatei verarbeiten. Die latin-1 Lösung in der Frage funktioniert wirklich zufällig.

In Ihrem Beispiel, das wäre so etwas wie:

with open('the/path', 'rb') as fi: 
    data = fi.read().replace(b'old data', b'new data') 
with open('other/path', 'wb') as fo: 
    fo.write(data) 

Dies ist in der Nähe zu dem, was für Sie fragen - soweit ich verstehe Sie nicht einmal über das Feld mit möglicherweise unterschiedlicher Codierung nicht kümmern - Sie Ich möchte nur etwas Inhalt ändern und den Rest der Datei so kopieren, wie sie ist. Im Binärmodus können Sie dies tun.