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

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

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

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

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

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

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

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

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

(«Прекрасная зелень!»).

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

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

Спасибо заранее! Маркус

решение1

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

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

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

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

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

Однострочник (см. 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!

Версия на 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))

решение2

Тема письма сама по себе является заголовком, а заголовки должны содержать только символы 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($_);'

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

Связанный контент