Como posso excluir U + 200B (espaço de largura zero) usando o sed

15

Eu tenho um arquivo muito grande que possui espaços de largura zero espalhados por todo. Leva muito tempo para abrir e editar usando, vientão eu gostaria de excluir todas as instâncias do personagem usando sed. O problema é que não consigo descobrir como combinar o personagem! Eu tentei usar \u200B, \x{200b}. Alguma ideia?

Estou executando o CentOS 5, se isso ajuda em tudo.

thetaiko
fonte
Sua cópia do sed suporta a codificação Unicode com a qual o arquivo está codificado? Se não há provavelmente nenhuma boa maneira de fazê-lo corretamente com sed, e é melhor usar um script python ou algo assim ...
janc
@ JanC - na verdade, eu fui com Python. O arquivo é codificado com utf8, parece padrão o suficiente para que qualquer coisa possa processá-lo. Adicionei meu script python abaixo, caso seja útil para qualquer pessoa.
perfil completo de thetaiko

Respostas:

11

Isso parece funcionar para mim:

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

Demonstração:

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

Baseado parcialmente na resposta de Gilles:

tr -d $(/usr/bin/printf "\u200b") < inputfile
Dennis Williamson
fonte
Perfeito - era exatamente isso que eu estava procurando. Na verdade, notei o mesmo conjunto de caracteres ( \xe2\x80\x8b) ao examinar algumas seqüências de amostra em Python. Obrigado!
Thetaiko
4

O comportamento do GNU sed com UTF-8 não parece estar muito bem definido. Experimentalmente, você pode substituir os bytes da representação UTF-8:

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

Como alternativa, você pode digitar o caractere no seu shell e usar qualquer um dos comandos padrão em um código de idioma UTF-8:

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

No zsh, você também pode inserir o caractere através de uma sequência de escape:

<old tr -d $'\u200B' >new
Gilles
fonte
A partir de 4,2 Bash, sequências Unicode são suportados por echo -e, printfcadeias de formato e ANSI citado cordas (por exemplo echo -e '\u1E4F', printf '\u01DD %s\n' 'X', mkdir $'\u0250)
Dennis Williamson
0

Bem, a menos que alguém tenha alguma idéia de como sedfazer isso (pelo qual ainda estou interessado, a propósito), é Python para o resgate ...

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
fonte
2
Se você pretende alcançar as grandes armas, e quanto mais simples perl -C -pe 's/\x{200B}//g'?
Gilles
+1 ao Gilles, que também funciona no Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfileresulta em yourfile fixo e um backup no yourfile.bak
MarkHu