Frage Wie konvertiere ich UTF-8 Sonderzeichen in Bash?


Ich schreibe ein Skript, das JPEG-Anhänge aus E-Mails extrahiert und speichert und an imagemagick weitergibt. Allerdings lebe ich in Deutschland und Sonderzeichen in E-Mail-Text / Thema wie "ö", "ä", "ü" und "ß" sind ziemlich häufig.

Ich extrahiere das Thema mit formail:

    SUBJECT=$(formail -zxSubject: <"$file")

und das ergibt:

  • =? UTF-8? Q? Meine_G = c3 = bcte? =

("Meine Güte") oder noch schlimmer

  • =? UTF-8? B? U2Now7ZuZSBHcsO8w59lIQ ==? =

("Schöne Grüße!").

Ich versuche, einen Teil des Themas als Dateinamen und als Bildmagie Text Annotation zu verwenden, die offensichtlich nicht funktioniert.

Wie konvertiere ich diesen UTF-8-Text in einen Text mit Sonderzeichen in bash?

Danke im Voraus! Markus


4
2017-09-12 23:16


Ursprung


Leerzeichen zwischen Wörtern und Satzzeichen fehlen ebenfalls :( - Markus


Antworten:


Wie konvertiere ich diesen UTF-8-Text in einen Text mit Sonderzeichen in bash?

Was du hast, ist nicht ganz "UTF-8 Text". Du tatsächlich wollen einfacher UTF-8-Text als Ausgabe, wie es Linux überall für "Sonderzeichen" verwendet.

Ihre Eingabe ist stattdessen MIME (RFC 2047) kodierte UTF-8. Das "Q" markiert den Quoted-Printable-Modus und "B" markiert den Base64-Modus. Unter anderem Perls Encode :: MIME :: Header kann verwendet werden, um beide zu dekodieren:

#!/usr/bin/env perl
use open qw(:std :utf8);
use Encode qw(decode);

while (my $line = <STDIN>) {
        print decode("MIME-Header", $line);
}

Oneliner (siehe perldoc perlrun zur Erklärung):

perl -CS -MEncode -ne 'print decode("MIME-Header", $_)'

Dies kann jedes Format als Eingabe annehmen:

$ echo "Subject: =?UTF-8?Q?Meine_G=c3=bcte?=, \
                 =?UTF-8?B?U2Now7ZuZSBHcsO8w59lIQ==?=" | perl ./decode.pl
Subject: Meine Güte, Schöne Grüße!

6
2017-09-13 00:10



Das Einzeiler hat bei mir nicht funktioniert. (siehe @Blami). Aber der PL-Code hat gut funktioniert. Wenn ich das letzte Skript verwendete, wurde der Base64-Teil überhaupt nicht codiert. Nicht einmal wenn ich nur diesen Teil ausprobierte. Ihre Erklärung hat mir auch geholfen. - Markus


E-Mail-Betreff selbst ist Header und Header dürfen nur ASCII-Zeichen enthalten. Aus diesem Grund muss UTF-8 (oder ein anderer Nicht-ASCII-Zeichensatz) codiert werden.

Diese Art der Codierung von Nicht-ASCII-Zeichen in ASCII wird in RFC 1342 beschrieben.

Grundsätzlich hat das codierte Subjekt folgendes Format (wie Sie bereits in Ihren Beispielen aufgelistet haben):

=?charset?encoding?encoded-text?=

Basierend auf dem Kodierungswert wird kodierter Text entweder als quoted-printable (Q) oder als base64 (B) dekodiert.

Um eine lesbare Form zu erhalten, müssen Sie den codierten Textteil des Subjektheaderwertes an Programm übergeben, das sie entschlüsselt. Ich glaube, es gibt einige eigenständige Befehle (uudecode), aber ich bevorzuge Perl-Einzeiler:

Für quoted-printable:

perl -pe 'use MIME::QuotedPrint; $_=MIME::QuotedPrint::decode($_);'

und für base64:

perl -pe 'use MIME::Base64; $_=MIME::Base64::decode($_);'

Stellen Sie sicher, dass Sie nur den codierten Textabschnitt und nicht den gesamten Betreffheaderwert übergeben.


5
2017-09-13 00:10



Danke für deinen Kommentar! Ich habe viel von deiner ausführlichen Erklärung gelernt. Allerdings konnte ich die One-Liner nicht richtig laufen lassen (in Putty auf Raspberry Pi). Aber ich bin sicher, dass dies nur wegen meiner schlechten Linuxfähigkeiten ist. Ich benutzte echo "=? UT ...:" | Perl ... und das Ergebnis war "=? UTF-8? Q? Meine_Güte?". Nur das "ü" wurde übersetzt. @grawitys bereitgestelltes .pl-Skript hat gute Ergebnisse erzielt. - Markus