ubuntuusers.de

.lnk-Dateien konvertieren (grep / iconv)

Status: Ungelöst | Ubuntu-Version: Kubuntu 18.04 (Bionic Beaver)
Antworten |

michahe

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Hallo,

in einem von einem WINDOWS-PC übernommenem Datenbestand habe ich eine größere Anzahl .lnk-Files (WINDOWS-Verknüpfungen, in allen Fällen auf PDF oder Office-Dateien); diese möchte ich auflesen und dann durch Soft-Links ersetzen.

Erster Schritt: Auflisten der .lnk-Dateien –> OK

$ find -name "*.lnk"
./SID - Doku 55 - Systeme für mich.pdf.lnk
./SID - Doku 57 - Office.pdf.lnk

Zweiter Schritt: Inhalt der .lnk-Datei auslesen (Quelle) –> teilweise OK, aber Namen von Ziel-Dateien mit Umlauten werden verstümmelt:

$find  -iname \*.lnk -exec strings "{}" \; | egrep -i "^[[:alnum:] äöüÄÖÜß]:\\\\"
C:\Daten\SID - Doku 55 - Systeme f 
C:\Daten\Projekte\Doku 57 - Office.pdf

Problem (wie hier) der Zeichensatz-Kodierung? Erfolglos habe iconv ich versucht:

iconv -f ISO_8859-15  -t UTF-8 "SID - Doku 55 - Systeme für mich.pdf.lnk"  -o   "neuSID - Doku 55 - Systeme für mich.pdf.lnk"

Das Ergebnis des egrep-Befehls bleibt für beide Versionen verstümmelt.

Wie kann ich die Aufgabe trotzdem lösen? Wie lässt sich die Kodierung der .lnk-Files herausfinden?

Meine Zeichensatz-Kodierung:

$ file /var/log/syslog
/var/log/syslog: UTF-8 Unicode text, with very long lines

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9783

Wohnort: Münster

michahe schrieb:

[…] von einem WINDOWS-PC übernommenem Datenbestand

… der logischerweise ein bei Windows üblicher Zeichensatz und eine bei Windows übliche Codierung verwendet. Das kann sein:

  • Ein spezieller, von Microsoft erfundener 8-Bit Zeichensatz wie z.B. CP1252, CP437, CP850 mit flacher Codierung, d.h. jedes der 256 Zeichen wird durch sich selbst codiert.

  • Oder: Ein genormter 16-Bit Zeichensatz (Unicode) mit der ebenfalls genormten Codierung UTF-16.

[…]

iconv -f ISO_8859-15  -t UTF-8 "SID - Doku 55 - Systeme für mich.pdf.lnk"  -o   "neuSID - Doku 55 - Systeme für mich.pdf.lnk"

Die genormten 8-Bit Zeichensätze ISO-8859 verwendet Windows nicht, allerdings ähneln die CPxxx-Zeichensätze ISO-8859. Manchmal wird in der Windows-Welt fälschlicherweise behauptet, es wäre tatsächlich ISO-8859.

Linux-Systeme verwenden in der Regel entweder ISO-8859 (deren Verwendung ist aber rückläufig) oder moderner Unicode mit der Codierung UTF-8, so auch bei Ubuntu.

iconv ist schon das richtige Werkzeug, aber Du musst herausfinden, welchen Zeichensatz und Codierung das Windows-System verwendet hat.

michahe

(Themenstarter)

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Danke kB,

… der logischerweise ein bei Windows üblicher Zeichensatz und eine bei Windows übliche Codierung verwendet. Das kann sein:

  • Ein spezieller, von Microsoft erfundener 8-Bit Zeichensatz wie z.B. CP1252, CP437, CP850 mit flacher Codierung, d.h. jedes der 256 Zeichen wird durch sich selbst codiert.

  • Oder: Ein genormter 16-Bit Zeichensatz (Unicode) mit der ebenfalls genormten Codierung UTF-16.

Folgendes habe ich versucht (in meinem Eingangsposting war ein Fehler im find Befehl:

.lnk-Files finden:

$ find -name "*.lnk"

Versuche, den Zeichensatz zu konvertieren, die ersten drei liefern Fehlermeldungen:

$ iconv -f CP1252 -t UTF8 "SIDfür.pdf.lnk"           -o  "SIDfürCP1252.pdf.lnk"
iconv: ungültige Eingabe-Sequenz an der Stelle 49

$ iconv -f WINDOWS-1250     -t UTF8 "SIDfür.pdf.lnk" -o  "SIDfürWINDOWS-1250.pdf.lnk"
iconv: ungültige Eingabe-Sequenz an der Stelle 90

$ iconv -f UTF16  -t UTF8 "SIDfür.pdf.lnk"           -o  "SIDfürUTF16.pdf.lnk"
iconv: unvollständige Zeichen- oder Shift-Folge am Ende des Puffers

Vier weitere liefern keinen Fehler:

$ iconv -f CP437  -t UTF8 "SIDfür.pdf.lnk"           -o  "SIDfürCP437.pdf.lnk"
$ iconv -f CP850  -t UTF8 "SIDfür.pdf.lnk"           -o  "SIDfürCP859.pdf.lnk"
$ iconv -f ISO_8859-15      -t UTF8 "SIDfür.pdf.lnk" -o  "SIDfürISO_8859-15.pdf.lnk"
$ iconv -f ISO_8859-15:1998 -t UTF8 "SIDfür.pdf.lnk" -o  "SIDfürISO_8859-15:1998.pdf.lnk"

Jetzt die Ziele der .lnk.Files auslesen:

$ find  -iname \*.lnk -exec strings "{}" \; | egrep -i "^[[:alnum:] äöüÄÖÜß]:\\\\"
C:\Daten\System f
C:\Daten\System f
C:\Daten\System f
C:\Daten\System f
C:\Daten\System f

Alle sind immer noch am Umlaut verstümmelt.

Dann habe ich mit dem Skript versucht, die Kodierung zu ermitteln:

$ bash encoding-finder.sh SIDfür.pdf.lnk für

Das liefert für alle Kodierungen: "Übereinstimmungen in Binärdatei (Standardeingabe)"!

Der WINDOWS-PC, von dem die .lnk-Files stammen, steht mir zur Verfügung. Kann ich dort feststellen, welche Kodierung verwendet wird?

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9783

Wohnort: Münster

michahe schrieb:

[…]> Der WINDOWS-PC, von dem die .lnk-Files stammen, steht mir zur Verfügung. Kann ich dort feststellen, welche Kodierung verwendet wird?

Das ist der einzig zuverlässige Weg. Beachte bitte: Windows benutzt für die Eingabeaufforderung (vulgo DOS-Fenster) und für Textdateien von GUI-Programmen unterschiedliche Zeichensätze und es gibt vielleicht auch einen Unterschied zwischen Dateiinhalten und Dateinamen. Den Zeichensatz für die Eingabeaufforderung kann man mit chcp anzeigen und festlegen, ungefähr so:

chcp 1252 

Du kannst unter Windows zum testen eine Textdatei anlegen mit dem Inhalt „äöüßÄÖܧ“ und ggf. weiteren Dir wichtig erscheinenden Zeichen, und diese auf das Linux-System bringen. Der Befehl hexdump bzw. hd unter Linux zeigt übrigens die tatsächlich vorhandenen Bytes an, z.B.:

$ echo -n 'äöüßÄÖܧ' | hd
00000000  c3 a4 c3 b6 c3 bc c3 9f  c3 84 c3 96 c3 9c c2 a7  |................|
00000010
$ cat Testdatei | hd

michahe

(Themenstarter)

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Vielen Dank kB,

Du kannst unter Windows zum testen eine Textdatei anlegen mit dem Inhalt „äöüßÄÖܧ“ und ggf. weiteren Dir wichtig erscheinenden Zeichen, und diese auf das Linux-System bringen. Der Befehl hexdump bzw. hd unter Linux zeigt übrigens die tatsächlich vorhandenen Bytes an, z.B.:

$ echo -n 'äöüßÄÖܧ' | hd
00000000  c3 a4 c3 b6 c3 bc c3 9f  c3 84 c3 96 c3 9c c2 a7  |................|
00000010
$ cat Testdatei | hd

Das mit dem hexzump ist ja prima, ich wollte schon einen HEX-Editor installieren. Ich habe direkt die .lnk-Datei verwendet:

cat SIDfür.pdf.lnk | hd

Das liefert in der betreffenden Zeile (_ für BLANK verwendet):

Klartext: _  f  .  r  _  D  a  c  h  _  u  n  d  _  F  a
HEX-Code: 20 66 fc 72 20 44 61 63 68 20 75 6e 64 20 46 61 

Das Zeichen 'ü' ist also HEX fc. Gemäß dieser Seite sollte das Cp1252, ISO 8859-1 oder ISO 8859-15 sein. Also noch 8859-1 ergänzt und geprüft:

$ iconv -f ISO_8859-1       -t UTF8 "SIDfür.pdf.lnk" -o  "SIDfürISO_8859-1.pdf.lnk"
$ find  -iname \*.lnk -exec strings "{}" \; | egrep -i "^[[:alnum:] äöüÄÖÜß]:\\\\"

Wieder sind alle verstümmelt. Habe ich einen Fehler im egrep-Befehl?

Nachtrag: Dieses Perl-Skript liefert das Link-Ziel vollständig bis zur Extension, allerdings wird das 'ü' als kopfstehendes '?' ausgegeben.

Antworten |