Wie konvertiere ich UTF-8-Sonderzeichen in Bash?

Wie konvertiere ich UTF-8-Sonderzeichen in Bash?

Ich schreibe an einem Skript, das JPEG-Anhänge aus E-Mails extrahiert, speichert und an Imagemagick weiterleitet. Ich lebe jedoch in Deutschland und Sonderzeichen im E-Mail-Text/Betreff wie „ö“, „ä“, „ü“ und „ß“ sind ziemlich üblich.

Ich extrahiere den Betreff mit Formail:

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

und das Ergebnis ist:

  • =?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 Betreffs als Dateinamen und als ImageMagick-Textanmerkung zu verwenden, was offensichtlich nicht funktioniert.

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

Vielen Dank im Voraus! Markus

Antwort1

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

Was Sie haben, ist nichtganz"UTF-8-Text". Sie eigentlichwolleneinfacher UTF-8-Text alsAusgabe, da dies unter Linux überall für „Sonderzeichen“ verwendet wird.

Ihre Eingabe ist stattdessen MIME (RFC 2047) kodiert in UTF-8. Das "Q" steht für den Quoted-Printable-Modus und das "B" für den Base64-Modus. Unter anderemKodierung::MIME::Headerkann zum Dekodieren von beidem verwendet werden:

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

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

Oneliner ( perldoc perlrunErklärung siehe):

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

Als Eingabe kann jedes beliebige Format verwendet werden:

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

Eine Version in Python 3:

#!/usr/bin/env python3
import email.header, sys

words = email.header.decode_header(sys.stdin.read())
words = [s.decode(c or "utf-8") for (s, c) in words]
print("".join(words))

Antwort2

Der Betreff der E-Mail selbst ist die Kopfzeile und Kopfzeilen dürfen nur ASCII-Zeichen enthalten. Aus diesem Grund muss der Betreff in UTF-8 (oder einem anderen nicht-ASCII-Zeichensatz) kodiert sein.

Diese Möglichkeit der Kodierung von Nicht-ASCII-Zeichen in ASCII wird in RFC 1342 beschrieben.

Der kodierte Betreff hat grundsätzlich (wie Du in Deinen Beispielen bereits aufgeführt hast) folgendes Format:

=?charset?encoding?encoded-text?=

Basierend auf dem Kodierungswert wird der kodierte Text entweder als Quoted-Printable (Q) oder als Base64 (B) dekodiert.

Um eine für Menschen lesbare Form zu erhalten, müssen Sie den codierten Textteil des Betreffzeilenwerts an ein Programm übergeben, das ihn decodiert. Ich glaube, es gibt einige eigenständige Befehle, um das zu tun (uudecode), aber ich bevorzuge die Verwendung von Perl-Einzeilern:

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 verschlüsselten Textteil und nicht den gesamten Betreff-Header-Wert übergeben.

verwandte Informationen