makroll10
Goto Top

Powershell Fehler bei Datei Umwandlung von UTF8 auf ANSI

Hallo,

ich möchte eine Datei mit utf8-Codierung per Powershell in eine Datei mit ansi-Codierung umwandeln.

Aktuell versuche ich das mit dem folgenden Powershell-Script:
Get-Content C:\Temp\Test-utf8.txt -Raw -Encoding utf8 | Out-File C:\Temp\Test-ansi.txt -Encoding Default

Die Datei: Test-utf8.txt enthält die folgenden Testdaten:
01.10.20,00099999,Möwe,Maxi

Die Umwandlung von utf8 --> ansi funktioniert in diesem Fall einwandfrei. Die Datei: Test-ansi.txt hat die Codierung: ansi.

Bei dem gleichen Programmaufruf, nur mit den folgenden leicht geänderten Daten (Möwe gegen Moewe getauscht):
01.10.20,00099999,Moewe,Maxi

wird zwar die Datei: Test-ansi.txt erzeugt. Die Datei: Test-ansi.txt hat aber immer noch eine utf8-Codierung.

Erklären kann ich mir das nicht..

Vielleicht hat ja jemand einen Tipp für mich. Herzlichen Dank im Voraus....

Markus

Content-ID: 4479114215

Url: https://administrator.de/contentid/4479114215

Ausgedruckt am: 26.11.2024 um 02:11 Uhr

emeriks
emeriks 02.11.2022 um 08:46:35 Uhr
Goto Top
Hi,
und was kommt raus, wenn Du beim Out-File explizit ANSI als -Encoding angibts?

E.
makroll10
makroll10 02.11.2022 um 09:36:31 Uhr
Goto Top
Hallo,

dann wird die folgenden Fehlermeldung ausgegeben:
Das Argument "Ansi" gehört nicht zu dem vom ValidateSet-Attribut angegebenen Satz ...

Also scheint Ansi kein gültiges Argument zu sein....

Markus
TwistedAir
TwistedAir 02.11.2022 um 09:46:47 Uhr
Goto Top
Hi!

Reference "Out-File", Parameter "-Encoding":
Specifies the type of encoding for the target file. The default value is utf8NoBOM.

Beginning with PowerShell 6.2, the Encoding parameter also allows numeric IDs of registered code pages (like -Encoding 1251) or string names of registered code pages (like -Encoding "windows-1251")

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell ...

Die Codepage für " Western European (Windows)" ist 1252.

Gruß
TA
4400667902
4400667902 02.11.2022 aktualisiert um 12:14:23 Uhr
Goto Top
Beginning with PowerShell 6.2
Geht auch mit der 5.1 wenn man die .NET Functions bemüht.
[IO.File]::WriteAllText('C:\Temp\Test-ansi.txt',(Get-Content 'C:\Temp\Test-utf8.txt' -Raw -Encoding UTF8),[System.Text.Encoding]::GetEncoding(1252))  
TK1987
TK1987 02.11.2022 aktualisiert um 15:47:03 Uhr
Goto Top
Moin Markus,

Zitat von @makroll10:
Bei dem gleichen Programmaufruf, nur mit den folgenden leicht geänderten Daten (Möwe gegen Moewe getauscht):
01.10.20,00099999,Moewe,Maxi

wird zwar die Datei: Test-ansi.txt erzeugt. Die Datei: Test-ansi.txt hat aber immer noch eine utf8-Codierung.
das ist ganz normal.

Bei Kodierungen ohne BOM gibt es (erst mal) keine Anhaltspunkte, anhand derer ein Editor die verwendete Kodierung erkennen könnte.
Sobald du jedoch spezielle Zeichen wie eben Umlaute verwendest, können die Editoren dann interpretieren, zu welcher Kodierung die verwendeten Zeichen passen.

Gruß Thomas
makroll10
makroll10 02.11.2022 um 22:25:49 Uhr
Goto Top
Hallo,

vielen Dank vorab...

Ich habe die verschiedenen Vorschläge ausprobiert. Leider ohne Erfolg. Ich denke, dass es an meiner PS-Version (5.1) liegt...;-(

Um das Problem schlussendlich zu umgehen, konnte ich in eine der Spaltenüberschriften einen passenden Umlaut "einbauen" und es funktioniert...

Gruß Markus
TK1987
Lösung TK1987 02.11.2022 aktualisiert um 22:43:53 Uhr
Goto Top
Zitat von @makroll10:
Ich denke, dass es an meiner PS-Version (5.1) liegt...;-(
Nein, das Ganze hat überhaupt nichts mit Powershell zu tun. Auch wenn du diese Datei mit einem x-beliebigen Editor erstellst, bleibt das Problem.

back-to-topZum besseren Verständnis, machen wir ein kleines Praxisexperiment:

Erstelle eine Textdatei, die nur das Wort "Test" enthält. Diese lädst du mit:
Get-Content -Encoding Byte -path <datei>

Alternativ können wir auch die beiden Encoder laden
$UTF8 = [System.Text.Encoding]::UTF8
$ANSI = [System.Text.Encoding]::GetEncoding(1252)
und mit diesen jeweils das Wort "Test" in ein Bytearray umwandeln:
$UTF8.GetBytes("Test")  
$ANSI.GetBytes("Test")  

Bei allen Aufrufen werdet ihr immer die selben 4 Bytes erhalten, nämlich
PS C:\> "Test".ToCharArray()|%{"{0,3} = {1}" -f [int]$_,$_}
 84 = T
101 = e
115 = s
116 = t

Aus mehr als diesen 4 Bytes besteht diese Datei nicht - und diese 4 Bytes sind bei UTF8 & ANSI vollkommen identisch.
Nun die Millionen-€-Frage: Woher soll der Editor also nun wissen, um welche Kodierung es sich handelt?
- Geht nicht.

Nun nehmen wir einen Umlaut - bleiben wir einfach mal bei dem "ö" aus Möwe:
PS C:\> $UTF8.GetBytes('ö')
195
182

PS C:\> $ANSI.GetBytes('ö')
246

Wandeln wir die Bytefolge nun in die andere Kodierung um, wird schnell klar: Da kann was nicht stimmen.
PS C:\> $UTF8.GetString(@(246))
�

PS C:\> $ANSI.GetString(@(195,182))
ö
Genau so machen es auch die Texteditoren.

Wir können noch als abschließenden Test die jeweilige Bytefolge als Textdatei abspeichern:
[byte[]]@(246)     | Set-Content -Encoding Byte ansi.txt
[byte[]]@(195,182) | Set-Content -Encoding Byte utf8.txt
Wie ihr seht, haben wir eigentlich überhaupt keine Textkodierung definiert - sondern nur die Bytes exportiert. Der Editor zeigt dennoch bei beiden jeweils das Zeichen "ö" an, einmal als UFT8- und einmal als ANSI-Kodierung.

Gruß Thomas