ฉันจะลบ U + 200B (เว้นวรรคความกว้างเป็นศูนย์) ได้อย่างไรโดยใช้ sed


15

ฉันมีไฟล์ขนาดใหญ่มากที่มีช่องว่างที่มีความกว้างเป็นศูนย์กระจายอยู่ทั่ว มันต้องใช้เวลานานเกินไปในการเปิดและแก้ไขการใช้ดังนั้นฉันต้องการที่จะลบทุกกรณีของตัวละครโดยใช้vi sedปัญหาคือฉันไม่สามารถหาวิธีจับคู่ตัวละครได้! ฉันลองใช้\u200Bแล้ว\x{200b}. ความคิดใด ๆ

ฉันใช้ CentOS 5 ถ้านั่นช่วยได้ทั้งหมด


สำเนาของ sed ของคุณรองรับการเข้ารหัส Unicode ที่ไฟล์นั้นถูกเข้ารหัสด้วยหรือไม่? ถ้าไม่มีอาจจะไม่มีวิธีที่ดีในการทำอย่างถูกต้องกับ sed และคุณควรใช้สคริปต์ python หรือสิ่งที่เป็นเช่นนั้น ...
JanC

@JANC - ฉันไปกับ Python แล้ว ไฟล์ถูกเข้ารหัสด้วย utf8 ดูเหมือนเป็นมาตรฐานมากพอที่ทุกอย่างจะสามารถดำเนินการได้ ฉันเพิ่มสคริปต์หลามของฉันด้านล่างในกรณีที่เป็นประโยชน์กับทุกคน
thetaiko

คำตอบ:


11

ดูเหมือนว่าจะใช้งานได้สำหรับฉัน:

sed 's/\xe2\x80\x8b//g' inputfile

สาธิต:

$ /usr/bin/printf 'X\u200bY\u200bZ' | hexdump -C
00000000  58 e2 80 8b 59 e2 80 8b  5a                       |X...Y...Z|
$ /usr/bin/printf 'X\u200bY\u200bZ' | sed 's/\xe2\x80\x8b//g' | hexdump -C
00000000  58 59 5a                                          |XYZ|

แก้ไข:

อ้างอิงบางส่วนจากคำตอบของ Gilles:

tr -d $(/usr/bin/printf "\u200b") < inputfile

สมบูรณ์แบบ - นี่คือสิ่งที่ฉันกำลังมองหา ที่จริงแล้วฉันสังเกตเห็นชุดอักขระเดียวกัน ( \xe2\x80\x8b) เมื่อดูสตริงตัวอย่างใน Python ขอขอบคุณ!
thetaiko

4

พฤติกรรมของ GNU sed กับ UTF-8 ดูเหมือนจะไม่ค่อยชัดเจน จากการทดลองคุณสามารถแทนที่ไบต์ของการแทน UTF-8 ได้:

<old sed 's/\xe2\x80\e8b//g' >new

หรือคุณสามารถพิมพ์อักขระลงในเชลล์ของคุณและใช้คำสั่งมาตรฐานใด ๆ ในโลแคล UTF-8:

<old tr -d '​' >new
<old sed 's/​//g' >new

ใน zsh คุณยังสามารถป้อนตัวละครผ่านทางลำดับหนีได้:

<old tr -d $'\u200B' >new

ในฐานะของทุบตี 4.2 ลำดับ Unicode ได้รับการสนับสนุนโดยecho -e, printfสตริงรูปแบบและ ANSI อ้างสตริง (เช่นecho -e '\u1E4F', printf '\u01DD %s\n' 'X', mkdir $'\u0250)
หยุดชั่วคราวจนกว่าจะมีประกาศ

0

ดีเว้นแต่มีใครมีความคิดเกี่ยวกับวิธีการsedทำเช่นนี้ (ซึ่งฉันยังสนใจโดยวิธี) Python เพื่อช่วยเหลือ ...

import sys, re
pattern = re.compile(u"\u200b")
f = open(sys.stdin, "rb")
for line in f:
    a = pattern.sub("", line.decode("utf8"))
    print a.encode("utf8"),
f.close()

2
หากคุณกำลังจะไปถึงปืนใหญ่แล้วมันง่ายกว่านี้อีกperl -C -pe 's/\x{200B}//g'ล่ะ?
Gilles 'หยุดความชั่วร้าย'

+1 ถึง Gilles ซึ่งทำงานบน Mac OSX perl -C -pi.bak -e 's/\x{200B}//g' yourfileผลลัพธ์ใน yourfile ได้รับการแก้ไขและสำรองใน yourfile.bak
MarkHu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.