tr: แปลง apostrophe เป็น ASCII


11

ฉันพยายามที่จะแปลงขวาคำพูดขีดเดียวกับผู้Apostrophetrใช้

tr "`echo -e '\xE2\x80\x99'`" "`echo -e '\x27'`" < a > b

กำหนดไฟล์ที่เข้ารหัส UTF-8 ชื่อaซึ่งมีตัวอย่างนี้:

Were not a different species
All alone?” Jeth mentioned.

OS X ใช้ BSD trและสร้างผลลัพธ์ที่ดี:

We're not a different species
“All alone?” Jeth mentioned.

Ubuntu ใช้ GNU trและสร้างผลลัพธ์ที่น่ารังเกียจนี้:

We'''re not a different species
''<9C>All alone?''<9D> Jeth mentioned.

ฉันจะบรรลุการแปลงนี้ใน Ubuntu ได้อย่างไร


ลองอีกครั้ง: tr $ '\ xE2 \ x80 \ x99' $ '\ x27' <a> b พร้อมผลลัพธ์เดียวกัน
plamtrue

1
นี่เป็นเรื่องดีที่จะรู้ว่าเครื่องหมายอัญประกาศ ASCII และ Unicode
αғsнιη

2
echo It’s easy | perl -CS -Mutf8 -pe "tr/’/'/"
tchrist

คำตอบ:


16

คุณสามารถลองใช้เครื่องมืออื่น ๆ เช่นsed:

$ sed "s/’/'/g" <a
We're not a different species
“All alone?” Jeth mentioned.

หรือเนื่องจากเราทำการแปลง่าย ๆ ให้ใช้yคำสั่งสำหรับsed:

$ sed "y/’/'/" <a
We're not a different species
“All alone?” Jeth mentioned.

GNUtrไม่สามารถใช้งานได้เนื่องจาก:

ปัจจุบันtrรองรับอักขระไบต์เดียวเท่านั้น ในที่สุดมันจะรองรับอักขระหลายไบต์; เมื่อทำเช่นนั้น-C ตัวเลือกจะทำให้มันเติมเต็มชุดของตัวละครในขณะที่-c จะทำให้มันเติมเต็มชุดของค่า ความแตกต่างนี้จะมีความสำคัญเฉพาะเมื่อค่าบางอย่างไม่ใช่อักขระและสามารถทำได้เฉพาะในโลแคลที่ใช้การเข้ารหัสหลายไบต์เมื่ออินพุตมีข้อผิดพลาดในการเข้ารหัส

และเป็นอักขระหลายไบต์:

$ echo -n \' | wc -c
1
$ echo -n  | wc -c  
3

1
sedดีกว่ามากสำหรับงานประเภทนี้
Kaz Wolfe

2
ที่จะอธิบายส่วนสุดท้ายเพิ่มเติม: trถูกใช้แทนที่แต่ละสามแยกไบต์ด้วย'เพราะฉะนั้น'''เช่นเดียวกับลำดับเสียที่มันได้เข้ามาแทนที่สองในสามของไบต์ในตัวละครที่คล้ายกันและ ควรทำความเข้าใจกับสามไบต์แทนพร้อมกันหมายถึงอักขระหนึ่งตัวและแทนที่มันแทน
deltab

สำหรับการที่ดีเข้าใจเป็นตัวสัญลักษณ์นอกจากนี้เราสามารถใช้tr -c '[:print:][:cntrl:]' '-'คำสั่งที่จะเปลี่ยนทุกที่ไม่ใช่การพิมพ์ตัวอักษรอื่น ๆ -นอกเหนือจากการควบคุมตัวอักษรที่ถูกต้องด้วย และคุณจะเห็นเดียวแปล 3 ---ไบต์ของตัวอักษรเช่น จุดที่ดีสำหรับตัวละครหลายไบต์
αғsнιη

9

หากคุณต้องการแปลงเครื่องหมายคำพูดคู่และอักขระอื่น ๆ คุณสามารถใช้GNUiconv :

$ iconv -f utf-8 -t ascii//translit < a
We're not a different species
"All alone?" Jeth mentioned.

//TRANSLITต่อท้ายบอกiconvว่าสำหรับตัวละครนอกละครของการเข้ารหัสเป้าหมาย (ที่นี่ ASCII) ก็สามารถใช้แทนตัวอักษรคล้ายกันหรือลำดับโดยอัตโนมัติ หากไม่มีคำต่อท้ายiconvก็จะยอมแพ้ทันทีที่พบว่าตัวละครที่พูดไม่ได้

โปรดทราบว่า//TRANSLITน่าจะเป็นส่วนขยายของ GNU: POSIXiconvไม่รองรับ


+1 หากคุณกำลังแปลงข้อความจากชุดอักขระหนึ่ง (หรือการเข้ารหัส) ไปยังอีกชุดหนึ่งคุณสามารถใช้เครื่องมือที่ออกแบบมาเพื่อจุดประสงค์นั้นได้
RedGrittyBrick

@deltab โซลูชันของคุณยังแทนที่เครื่องหมายคำพูดคู่ซึ่ง OP ไม่ต้องการแทนที่
αғsнιη

@KasiyA บางทีพวกเขาควรจะ
gerrit

3

คุณสามารถใช้หนึ่งในawkโซลูชันเหล่านี้:

awk '{gsub(/\xE2\x80\x99/, "\x27");print}' file # with Hex ASCII code

awk '{gsub(/’/, "\x27");print}' file

awk '{gsub(/\342\200\231/, "\47");print}'  file # with Octal ASCII code

awk '{gsub(/’/, "\47");print}' file

หรือ

awk '{gsub(/’/, "'"'"'");print}' file

0

ใช้-sตัวเลือกของtr :

$ echo "We’re not a different species"|tr -s "’" "'"
We're not a different species

จากman tr :

--truncate-set1
          first truncate SET1 to length of SET2

1
โซลูชันของคุณยังแทนที่เครื่องหมายคำพูดคู่ซึ่ง OP ไม่ต้องการแทนที่ด้วย
αғsнιη

อ่าแน่นอนขอบคุณที่ชี้เรื่องนี้ออกมา ฉันจะทิ้งคำตอบนี้ไว้เพื่ออ้างอิง
Skippy le Grand Gourou
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.