Bagaimana saya bisa menghapus U + 200B (Nol-lebar ruang) menggunakan sed

15

Saya memiliki file yang sangat besar yang memiliki spasi selebar nol. Dibutuhkan waktu terlalu lama untuk membuka dan mengedit menggunakan vijadi saya ingin menghapus semua instance dari karakter menggunakan sed. Masalahnya adalah, saya tidak tahu bagaimana cara mencocokkan karakter! Saya sudah mencoba menggunakan \u200B, \x{200b}. Ada ide?

Saya menjalankan CentOS 5 jika itu membantu sama sekali.

thaiko
sumber
Apakah salinan sed Anda mendukung pengodean Unicode yang dikodekan dengan file tersebut? Jika tidak, mungkin tidak ada cara yang baik untuk melakukannya dengan benar dengan sed, dan Anda sebaiknya menggunakan skrip python atau sesuatu seperti itu ...
JanC
@ JC - memang, saya sudah pergi dengan Python. File dikodekan dengan utf8, tampaknya cukup standar sehingga apa pun harus dapat memprosesnya. Saya telah menambahkan skrip python saya di bawah ini, jika berguna bagi siapa pun.
thetaiko

Jawaban:

11

Ini sepertinya bekerja untuk saya:

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

Demonstrasi:

$ /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|

Edit:

Didasarkan sebagian pada jawaban Gilles:

tr -d $(/usr/bin/printf "\u200b") < inputfile
Dijeda sampai pemberitahuan lebih lanjut.
sumber
Sempurna - inilah yang saya cari. Bahkan, saya perhatikan bahwa set karakter yang sama ( \xe2\x80\x8b) ketika melihat beberapa string sampel dengan Python. Terima kasih!
thetaiko
4

Perilaku sed GNU dengan UTF-8 tampaknya tidak didefinisikan dengan sangat baik. Secara eksperimental, Anda dapat membuatnya menggantikan byte dari representasi UTF-8:

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

Sebagai alternatif, Anda dapat mengetik karakter ke shell Anda dan menggunakan salah satu perintah standar di lokal UTF-8:

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

Di zsh, Anda juga dapat memasukkan karakter melalui urutan pelarian:

<old tr -d $'\u200B' >new
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Pada Bash 4.2, urutan Unicode didukung oleh echo -e, printfstring Format dan ANSI dikutip string (misalnya echo -e '\u1E4F', printf '\u01DD %s\n' 'X', mkdir $'\u0250)
Dihentikan Sementara sampai pemberitahuan lebih lanjut.
0

Yah, kecuali ada yang punya ide untuk bagaimana sedmelakukan ini (yang saya masih tertarik, omong-omong) Python untuk menyelamatkan ...

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()
thaiko
sumber
2
Jika Anda akan meraih senjata besar, bagaimana dengan yang lebih sederhana perl -C -pe 's/\x{200B}//g'?
Gilles 'SO- stop being evil'
+1 ke Gilles yang juga berfungsi di Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfilehasil di file Anda diperbaiki dan cadangan di
file Anda.bak