5

Как я могу grep для символа Unicode 'ZERO WIDTH SPACE' (U+200B) в Linux?

$ grep '%U200B' filename?

3 ответа3

5

Сначала напечатаем одно:

$ printf %b '\u200b' | uniname
character  byte       UTF-32   encoded as     glyph   name
        0          0  00200B   E2 80 8B               ZERO WIDTH SPACE

Теперь мы должны иметь возможность использовать тот же формат для его поиска (используя Bash):

$ printf %b '\u200b' | grep -q "$(printf %b '\u200b')"
$ echo $?
0

Хитрость в том, что printf %b обрабатывает аргументы как закодированные символы, поэтому вы можете использовать \x для печати однобайтовых символов и \u * для печати многобайтовых символов.

Чтобы найти его в файле, просто сделайте это:

grep "$(printf %b '\u200b')" filename

* В спецификации POSIX не совсем понятно, как работает %b . Страница printf сообщает:«Спецификация преобразования% b [...] была добавлена здесь как переносимый способ обработки -escapes, развернутых в строковых операндах, как это предусмотрено утилитой echo», а страница echo показывает единственный недокументированный пример ее использовать.

Тестовое задание:

$ printf %b '\u200b' > test.txt
$ grep -q "$(printf %b '\u200b')" test.txt
$ echo $?
0
4

Следующее, отлично работает. Я создал файл с BabelMap(Google) и использовал его вариант сохранения.

Создан файл с номерами строк 1-5, а в строке 4 добавлен пробел нулевой длины:

> hexdump testout.txt -C                 
00000000  31 0a 32 0a 32 0a 33 0a  34 20 e2 80 8b 0a 35 0a  |1.2.2.3.4 ....5.|
00000010

Обратите внимание на кодировку utf8 символа 'e2808b' в файле.

Этот простой grep находит правильную строку:

> grep $'\u200b' testout.txt  
4 ​
> grep $'\u200b' testout.txt|hexdump -C
00000000  34 20 e2 80 8b 0a                                 |4 ....|
00000006 

FWIW, мои GREP_OPTIONS установлены: "--color = auto -I -D skip -d skip", но я не думаю, что какие-либо из них актуальны.

0

Вы также можете использовать регулярные выражения Perl с GNU grep

grep --perl-regexp '\x {200B}' filename

В macos это сложнее, так как BSD grep, который поставляется с ним, не поддерживает многобайтовый режим. Однако GNU grep может быть установлен через Homebrew, где он доступен как ggrep .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .