Jak mogę usunąć U + 200B (przestrzeń zerowej szerokości) za pomocą sed

15

Mam bardzo duży plik z rozproszonymi spacjami o zerowej szerokości. Otwarcie i edycja za pomocą zajmuje zbyt dużo czasu, vidlatego chciałbym usunąć wszystkie wystąpienia postaci używającej sed. Problem polega na tym, że nie potrafię dopasować postaci! Próbowałem za pomocą \u200B, \x{200b}. Jakieś pomysły?

Używam CentOS 5, jeśli to w ogóle pomaga.

thetaiko
źródło
Czy twoja kopia sed obsługuje kodowanie Unicode, w którym kodowany jest plik? Jeśli nie, prawdopodobnie nie ma dobrego sposobu, aby zrobić to poprawnie za pomocą sed, i lepiej użyć skryptu w Pythonie lub czegoś takiego ...
JanC
@JanC - rzeczywiście, korzystam z Pythona. Plik jest zakodowany za pomocą utf8, wydaje się na tyle standardowy, że wszystko powinno być w stanie go przetworzyć. Dodałem poniżej mój skrypt python, na wypadek, gdyby był użyteczny dla każdego.
thetaiko,

Odpowiedzi:

11

Wydaje mi się, że to działa:

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

Demonstracja:

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

Edytować:

Na podstawie częściowo odpowiedzi Gillesa:

tr -d $(/usr/bin/printf "\u200b") < inputfile
Wstrzymano do odwołania.
źródło
Idealnie - właśnie tego szukałem. W rzeczywistości zauważyłem ten sam zestaw znaków ( \xe2\x80\x8b), patrząc na niektóre ciągi znaków w Pythonie. Dziękuję Ci!
thetaiko,
4

Zachowanie GNU sed z UTF-8 nie wydaje się być zbyt dobrze zdefiniowane. Eksperymentalnie możesz sprawić, że zastąpi bajty reprezentacji UTF-8:

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

Alternatywnie możesz wpisać znak do swojej powłoki i użyć dowolnego ze standardowych poleceń w ustawieniach regionalnych UTF-8:

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

W Zsh możesz również wprowadzić postać poprzez sekwencję ucieczki:

<old tr -d $'\u200B' >new
Gilles „SO- przestań być zły”
źródło
Jak Basha 4.2, sekwencje Unicode są poparte echo -e, printfwielkoformatowych strun i ANSI notowane ciągi (np echo -e '\u1E4F', printf '\u01DD %s\n' 'X', mkdir $'\u0250)
wstrzymane do odwołania.
0

Cóż, chyba że ktoś ma jakieś pomysły, jak to sedzrobić (przy okazji, nadal mnie to interesuje). Python na ratunek ...

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()
thetaiko
źródło
2
Jeśli masz zamiar sięgnąć po duże działa, co powiesz na znacznie prostsze perl -C -pe 's/\x{200B}//g'?
Gilles „SO- przestań być zły”
+1 do Gillesa, który działa również na Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfileskutkuje naprawieniem twojego pliku i utworzeniem kopii zapasowej w twoim pliku.bak
MarkHu,