Comment puis-je supprimer U + 200B (espace de largeur nulle) en utilisant sed

15

J'ai un très gros fichier qui a des espaces de largeur nulle dispersés partout. Il faut trop de temps pour ouvrir et modifier en utilisant vidonc je voudrais supprimer toutes les instances du personnage en utilisant sed. Le problème est que je n'arrive pas à trouver comment faire correspondre le personnage! Je l' ai essayé d' utiliser \u200B, \x{200b}. Des idées?

J'utilise CentOS 5 si cela peut aider.

thetaiko
la source
Votre copie de sed prend-elle en charge le codage Unicode avec lequel le fichier est codé? Sinon, il n'y a probablement aucun bon moyen de le faire correctement avec sed, et vous feriez mieux d'utiliser un script python ou quelque chose comme ça ...
JanC
@JanC - en effet, je suis allé avec Python. Le fichier est encodé avec utf8, semble assez standard pour que tout soit capable de le traiter. J'ai ajouté mon script python ci-dessous, au cas où cela serait utile à n'importe qui.
thetaiko

Réponses:

11

Cela semble fonctionner pour moi:

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

Manifestation:

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

Éditer:

Basé en partie sur la réponse de Gilles:

tr -d $(/usr/bin/printf "\u200b") < inputfile
En pause jusqu'à nouvel ordre.
la source
Parfait - c'est exactement ce que je cherchais. En fait, j'ai remarqué ce même ensemble de caractères ( \xe2\x80\x8b) en regardant quelques exemples de chaînes en Python. Je vous remercie!
thetaiko
4

Le comportement de GNU sed avec UTF-8 ne semble pas très bien défini. Expérimentalement, vous pouvez lui faire remplacer les octets de la représentation UTF-8:

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

Alternativement, vous pouvez taper le caractère dans votre shell et utiliser l'une des commandes standard dans un environnement local UTF-8:

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

Dans zsh, vous pouvez également saisir le personnage via une séquence d'échappement:

<old tr -d $'\u200B' >new
Gilles 'SO- arrête d'être méchant'
la source
A partir de Bash 4.2, séquences Unicode sont pris en charge par echo -e, les printfchaînes de format et ANSI entre guillemets les chaînes (par exemple echo -e '\u1E4F', printf '\u01DD %s\n' 'X', mkdir $'\u0250)
Suspendu jusqu'à nouvel ordre.
0

Eh bien, à moins que quelqu'un n'ait des idées sur la façon de sedfaire cela (ce qui m'intéresse toujours, d'ailleurs) son Python à la rescousse ...

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
la source
2
Si vous allez chercher les gros canons, que diriez-vous du plus simple perl -C -pe 's/\x{200B}//g'?
Gilles 'SO- arrête d'être méchant'
+1 au Gilles qui fonctionne également sur Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfileentraîne la correction de yourfile et une sauvegarde dans yourfile.bak
MarkHu