web-dev-qa-db-ja.com

BashでUTF-8特殊文字を変換するにはどうすればよいですか?

メールからJPEG添付ファイルを抽出して保存し、それらをimagemagickに渡すスクリプトを書いています。ただし、私はドイツに住んでおり、メールのテキストや件名に「ö」、「ä」、「ü」、「ß」などの特殊文字がかなり一般的です。

私はformailで件名を抽出しています:

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

その結果は:

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

( "MeineGüte")またはさらに悪い

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

( "SchöneGrüße!")。

件名の一部をファイル名とimagemagickテキスト注釈として使用しようとしていますが、明らかに機能しません。

このUTF-8テキストをbashの特殊文字を含むテキストに変換するにはどうすればよいですか?

前もって感謝します!マーカス

7
Markus

このUTF-8テキストをbashの特殊文字を含むテキストに変換するにはどうすればよいですか?

あなたが持っているのはquite「UTF-8テキスト」ではありません。あなたは実際にwantプレーンUTF-8テキストをoutputとして、 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);
}

ワンライナー(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))
9
user1686

電子メールの件名自体はヘッダーであり、ヘッダーにはASCII文字のみを含める必要があります。これがUTF-8(またはその他の非ASCII文字セット)の件名をエンコードする必要がある理由です。

非ASCII文字をASCIIにエンコードするこの方法は、RFC1342で説明されています。

基本的に、エンコードされたサブジェクトは(すでに例にリストされているように)以下のフォーマットを持っています:

=?charset?encoding?encoded-text?=

エンコード値に基づいて、quoted-printable(Q)またはbase64(B)としてエンコードされたテキストがデコードされます。

人間が読める形式を取得するには、件名ヘッダー値のエンコードされたテキスト部分を、それをデコードするプログラムに渡す必要があります。それを行うためのスタンドアロンコマンド(uudecode)がいくつかあると思いますが、Perlワンライナーを使用することを好みます。

Quoted-printableの場合:

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

そしてbase64の場合:

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

件名のヘッダー値全体ではなく、エンコードされたテキスト部分のみを渡すようにしてください。

7
blami