Як можна видалити U + 200B (нульовий простір) за допомогою sed


15

У мене дуже великий файл, який має нульові ширини, розкидані по всьому. Відкривати та редагувати за допомогою потрібно занадто багато часу, viтому я хотів би видалити всі екземпляри символу sed. Проблема в тому, що я не можу зрозуміти, як відповідати персонажу! Я спробував з допомогою \u200B, \x{200b}. Будь-які ідеї?

Я запускаю CentOS 5, якщо це зовсім допомагає.


Чи підтримує ваша копія 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 ви також можете ввести символ через послідовність відходу:

<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()

2
Якщо ви збираєтеся дотягнутися до великих гармат, як щодо набагато простіших perl -C -pe 's/\x{200B}//g'?
Жил "ТАК - перестань бути злим"

+1 до Gilles, який також працює на Mac OSX. perl -C -pi.bak -e 's/\x{200B}//g' yourfileрезультати виправлені у
вашому файлі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.