6

Я пишу сценарий, который извлекает и сохраняет JPEG-вложения из электронных писем и передает их в imagemagick. Тем не менее, я живу в Германии, и специальные символы в тексте / теме письма, такие как "ö", "ä", "ü" и "ß", довольно распространены.

Я извлекаю тему с помощью почты:

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

и это приводит к:

  • знак равноUTF-8?Q?Meine_G = c3 = bcte?знак равно

("Meine Güte") или еще хуже

  • знак равноUTF-8?B?U2Now7ZuZSBHcsO8w59lIQ ==?знак равно

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

Я пытаюсь использовать часть предмета как имя файла и как текстовую аннотацию imagemagick, которая, очевидно, не работает.

Как мне преобразовать этот текст UTF-8 в текст со специальными символами в bash?

Заранее спасибо! Markus

2 ответа2

7

Как мне преобразовать этот текст UTF-8 в текст со специальными символами в bash?

То, что у вас есть, не совсем «текст UTF-8». На самом деле вам нужен простой текст UTF-8 в качестве вывода, поскольку это то, что Linux использует везде для "специальных символов".

Вместо этого вы вводите кодировку MIME (RFC 2047) в кодировке UTF-8. "Q" обозначает режим Quoted-Printable, а "B" обозначает режим Base64. Среди прочего, Perl Encode::MIME::Header может использоваться для декодирования обоих:

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

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

Oneliner (см. perldoc perlrun для объяснения):

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

Это может принять любой формат в качестве ввода:

$ 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

Тема письма сама по себе является заголовком, а заголовки должны содержать только символы ASCII. Вот почему объект UTF-8 (или любой другой кодировщик, не относящийся к ASCII) должен быть закодирован.

Этот способ кодирования не-ASCII символов в ASCII описан в RFC 1342.

По сути, закодированная тема имеет (как вы уже перечислили в своих примерах) следующий формат:

=?charset?encoding?encoded-text?=

На основе значения кодирования кодированный текст декодируется либо как цитируемый для печати (Q), либо как base64 (B).

Чтобы получить удобочитаемую форму, вам нужно передать кодированную текстовую часть значения заголовка субъекта в программу, которая его декодирует. Я полагаю, что для этого есть несколько автономных команд (uudecode), но я предпочитаю использовать Perl с одной строкой:

Для цитируемой печати:

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

и для base64:

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

Убедитесь, что вы передаете только часть закодированного текста, а не целое значение заголовка темы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .