Как я могу удалить U + 200B (пространство нулевой ширины), используя sed

15

У меня есть очень большой файл, в котором разбросаны пробелы нулевой ширины. Это занимает слишком много времени, чтобы открыть и редактировать, используя, viпоэтому я хотел бы удалить все экземпляры символа, используя sed. Проблема в том, что я не могу понять, как соответствовать характеру! Я попытался с помощью \u200B, \x{200b}. Есть идеи?

Я использую CentOS 5, если это поможет.

thetaiko
источник
Поддерживает ли ваша копия sed кодировку Unicode, которой кодируется файл? Если нет, то, вероятно, нет хорошего способа сделать это правильно с помощью sed, и вам лучше использовать скрипт на python или что-то в этом роде ...
JanC
@JanC - действительно, я пошел с Python. Файл закодирован с помощью utf8, кажется достаточно стандартным, чтобы что-нибудь могло его обработать. Я добавил свой скрипт на Python ниже, на случай, если он пригодится кому-либо.
thetaiko

Ответы:

11

Кажется, это работает для меня:

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

Демонстрация:

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

Редактировать:

Основано частично на ответе Жиля:

tr -d $(/usr/bin/printf "\u200b") < inputfile
Приостановлено до дальнейшего уведомления.
источник
Идеально - это именно то, что я искал. Фактически, я заметил тот же набор символов ( \xe2\x80\x8b) при просмотре некоторых примеров строк в Python. Спасибо!
Thetaiko
4

Поведение GNU sed с UTF-8 не очень четко определено. Экспериментально, вы можете заменить его байтами представления UTF-8:

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

Кроме того, вы можете ввести символ в свою оболочку и использовать любую из стандартных команд в локали UTF-8:

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

В zsh вы также можете ввести символ через escape-последовательность:

<old tr -d $'\u200B' >new
Жиль "ТАК - перестань быть злым"
источник
По состоянию на Bash 4.2, последовательности Unicode поддерживается echo -e, printfформат строка и ANSI кавычек (например echo -e '\u1E4F', printf '\u01DD %s\n' 'X', mkdir $'\u0250)
Приостановлено до дальнейшего уведомления.
0

Ну, если у кого-то нет идей, как заставить sedэто сделать (кстати, меня это все еще интересует) его Python на помощь ...

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
источник
2
Если вы собираетесь достать большие орудия, как насчет гораздо более простых perl -C -pe 's/\x{200B}//g'?
Жиль "ТАК - перестань быть злым"
+1 к Жилю, который также работает на Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfileв результате исправляется ваш файл и резервная копия в yourfile.bak
MarkHu