Bash에서 UTF-8 특수 문자를 어떻게 변환합니까?

Bash에서 UTF-8 특수 문자를 어떻게 변환합니까?

저는 이메일에서 JPEG 첨부 파일을 추출 및 저장하고 이를 imagemagick에 전달하는 스크립트를 작성 중입니다. 하지만 저는 독일에 살고 있으며 이메일 텍스트/제목에 "ö", "ä", "ü" 및 "ß"와 같은 특수 문자가 매우 일반적입니다.

Formail을 사용하여 주제를 추출하고 있습니다.

    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에서 특수 문자가 포함된 텍스트로 어떻게 변환합니까?

미리 감사드립니다! 마커스

답변1

이 UTF-8 텍스트를 bash에서 특수 문자가 포함된 텍스트로 어떻게 변환합니까?

당신이 가지고 있는 것은 그렇지 않습니다.상당히"UTF-8 텍스트". 당신은 실제로원하다일반 UTF-8 텍스트산출, Linux가 모든 곳에서 "특수 문자"에 사용하는 것이기 때문입니다.

대신 입력은 MIME(RFC 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);
}

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!

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?=

인코딩 값에 따라 인코딩된 텍스트는 quoted-printable(Q) 또는 base64(B)로 디코딩됩니다.

사람이 읽을 수 있는 형식을 얻으려면 제목 헤더 값의 인코딩된 텍스트 부분을 디코딩하는 프로그램에 전달해야 합니다. 나는 이를 수행하는 몇 가지 독립 실행형 명령(uudecode)이 있다고 생각하지만 Perl 한 줄짜리 명령을 사용하는 것을 선호합니다.

인용 인쇄용:

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

base64의 경우:

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

전체 제목 헤더 값이 아닌 인코딩된 텍스트 부분만 전달해야 합니다.

관련 정보