ฉันจะแปลงอักขระพิเศษ UTF-8 เป็น Bash ได้อย่างไร


6

ฉันกำลังเขียนสคริปต์ที่แยกและบันทึกไฟล์แนบ JPEG จากอีเมลและส่งต่อไปยัง imagemagick อย่างไรก็ตามฉันอาศัยอยู่ในเยอรมนีและตัวละครพิเศษในข้อความอีเมล์ / หัวเรื่องเป็น "ö", "ä", "ü" และ "ß" เป็นเรื่องธรรมดา

ฉันกำลังแยกหัวเรื่องด้วย formail:

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

และผลลัพธ์ใน:

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

("Meine Güte") หรือแย่กว่านั้น

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

("SchöneGrüße!")

ฉันพยายามใช้ส่วนหนึ่งของหัวเรื่องเป็นชื่อไฟล์และเป็นคำอธิบายประกอบแบบข้อความของ imagemagick ซึ่งเห็นได้ชัดว่าใช้งานไม่ได้

ฉันจะแปลงข้อความ UTF-8 นี้เป็นข้อความด้วยอักขระพิเศษใน bash ได้อย่างไร

ขอบคุณล่วงหน้า! มาร์คัส


ช่องว่างระหว่างคำและเครื่องหมายวรรคตอนขาดหายไปเช่นกัน :(
Markus

คำตอบ:


8

ฉันจะแปลงข้อความ UTF-8 นี้เป็นข้อความด้วยอักขระพิเศษใน bash ได้อย่างไร

สิ่งที่คุณต้องไม่ได้ค่อนข้าง "UTF-8 ข้อความ" คุณต้องการเอาท์พุทข้อความ UTF-8 ธรรมดาเพราะลีนุกซ์ใช้สำหรับ "อักขระพิเศษ" ทุกที่

ข้อมูลที่คุณป้อนแทนคือ MIME ( RFC 2047 ) ที่เข้ารหัส UTF-8 เครื่องหมาย "Q" หมายถึงโหมดที่พิมพ์ได้และ "B" หมายถึงโหมด Base64 ในหมู่คนอื่น ๆEncodeของ 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))

หนึ่งซับไม่ทำงานสำหรับฉัน (ดู @blami) แต่รหัส pl ทำงานได้ดี เมื่อฉันใช้สคริปต์สุดท้ายส่วน Base64 ไม่ได้เข้ารหัสเลย ไม่แม้แต่ตอนที่ฉันพยายามแค่ส่วนนั้น คำอธิบายของคุณช่วยฉันเช่นกัน
Markus

6

หัวเรื่องของอีเมลเองคือส่วนหัวและส่วนหัวต้องมีอักขระ ASCII เท่านั้น นี่คือสาเหตุที่ UTF-8 (หรือชุดอักขระที่ไม่ใช่ ASCII อื่น) ต้องเข้ารหัส

วิธีการเข้ารหัสอักขระที่ไม่ใช่ ASCII ใน ASCII นี้อธิบายไว้ใน RFC 1342

โดยพื้นฐานแล้วหัวเรื่องที่เข้ารหัสมี (ตามที่คุณระบุไว้ในตัวอย่างแล้ว) รูปแบบต่อไปนี้:

=?charset?encoding?encoded-text?=

ขึ้นอยู่กับค่าการเข้ารหัสถูกเข้ารหัส - ถอดรหัสข้อความทั้งที่ยกมาพิมพ์ (Q) หรือเป็น base64 (B)

เพื่อให้ได้รูปแบบที่มนุษย์อ่านได้คุณจะต้องผ่านส่วนข้อความที่เข้ารหัสของค่าส่วนหัวของหัวเรื่องไปยังโปรแกรมที่ถอดรหัส ฉันเชื่อว่ามีคำสั่งแบบสแตนด์อโลนที่จะทำ (uudecode) แต่ฉันชอบใช้ Perl one-liners:

สำหรับใบเสนอราคาที่พิมพ์ได้:

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

และสำหรับ base64:

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

ตรวจสอบให้แน่ใจว่าคุณผ่านเฉพาะส่วนข้อความที่เข้ารหัสเท่านั้นไม่ใช่ค่าส่วนหัวของหัวเรื่องทั้งหมด


ขอบคุณสำหรับความคิดเห็นของคุณ! ฉันเรียนรู้มากมายจากคำอธิบายโดยละเอียดของคุณ อย่างไรก็ตามฉันไม่สามารถให้หนึ่ง liners ทำงานอย่างถูกต้อง (ใน putty บนราสเบอร์รี่ pi) แต่ฉันแน่ใจว่านี่เป็นเพียงเพราะทักษะลินุกซ์ที่ไม่ดีของฉัน ฉันใช้ echo "=? UT ... :" | perl ... และผลลัพธ์คือ "=? UTF-8? Q? Meine_Güte?" แปลเฉพาะ "ü" เท่านั้น สคริปต์. pl ของ @grawity ที่ให้ไว้นั้นให้ผลลัพธ์ที่ดี
Markus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.