¿Cómo puedo eliminar U + 200B (espacio de ancho cero) usando sed

15

Tengo un archivo muy grande que tiene espacios de ancho cero dispersos por todas partes. Se tarda demasiado en abrir y editar usando, vipor lo que me gustaría eliminar todas las instancias del personaje usando sed. ¡El problema es que no puedo encontrar la manera de unir al personaje! He intentado usar \u200B, \x{200b}. ¿Algunas ideas?

Estoy ejecutando CentOS 5 si eso ayuda en absoluto.

thetaiko
fuente
¿Su copia de sed admite la codificación Unicode con la que está codificado el archivo? Si no, probablemente no haya una buena manera de hacerlo correctamente con sed, y será mejor que uses un script de Python o algo así ...
JanC
@ JanC: de hecho, me he ido con Python. El archivo está codificado con utf8, parece lo suficientemente estándar como para que cualquier cosa pueda procesarlo. He agregado mi script de python a continuación, en caso de que sea útil para alguien.
thetaiko

Respuestas:

11

Esto parece funcionar para mí:

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

Demostración:

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

Editar:

Basado parcialmente en la respuesta de Gilles:

tr -d $(/usr/bin/printf "\u200b") < inputfile
Pausado hasta nuevo aviso.
fuente
Perfecto, esto es exactamente lo que estaba buscando. De hecho, noté ese mismo conjunto de caracteres ( \xe2\x80\x8b) al mirar algunas cadenas de muestra en Python. ¡Gracias!
thetaiko
4

El comportamiento de GNU sed con UTF-8 no parece estar muy bien definido. Experimentalmente, puede hacer que reemplace los bytes de la representación UTF-8:

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

Alternativamente, puede escribir el carácter en su shell y usar cualquiera de los comandos estándar en un entorno local UTF-8:

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

En zsh, también puede ingresar el carácter a través de una secuencia de escape:

<old tr -d $'\u200B' >new
Gilles 'SO- deja de ser malvado'
fuente
A partir de Bash 4.2, las secuencias Unicode están soportadas por echo -e, printflas cadenas de formato y ANSI citan cadenas (por ejemplo echo -e '\u1E4F', printf '\u01DD %s\n' 'X', mkdir $'\u0250)
En pausa hasta nuevo aviso.
0

Bueno, a menos que alguien tenga alguna idea de cómo sedhacer esto (que todavía me interesa, por cierto), es Python al rescate ...

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
fuente
2
Si vas a alcanzar las armas grandes, ¿qué tal la más simple perl -C -pe 's/\x{200B}//g'?
Gilles 'SO- deja de ser malvado'
+1 a Gilles, que también funciona en Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfileresultados en su archivo fijo y una copia de seguridad en yourfile.bak
MarkHu