Странное поведение grep с символами CJK? (баш)

grep не может сопоставить определенные строки с символами CJK. Например.

  1. Создайте текстовый файл с содержимым ниже:
==ShellType.サモナu30FC==
  1. Используйте grep.
    >> grep "ShellType.サモナu30FC" test.txt
    (empty output)
    >> grep "ShellType.サモナ.*u30FC" test.txt
    ==ShellType.サモナu30FC==

Это ошибка grep или символы CJK нуждаются в особой обработке?
Как правильно выполнять поиск по строкам CJK с помощью grep или других надежных инструментов?

Система: Ubuntu 20.04
GNU bash, версия 5.0.17 (1) -release (x86_64-pc-linux-gnu)
grep (GNU grep) 3.4

1 ответ
1

Это не имеет ничего общего с CJK. Ты можешь использовать -o чтобы (более или менее) увидеть, что u на самом деле означает в grep:

[tom@ideapad ~]$ cat /tmp/meh 
==ShellType.サモナu30FC==
[tom@ideapad ~]$ grep -o 'u' /tmp/meh 
u
[tom@ideapad ~]$ grep -o '.u' /tmp/meh 
u
[tom@ideapad ~]$ grep -o '.*u' /tmp/meh 
==ShellType.サモナu
[tom@ideapad ~]$ grep -o '.*.*u' /tmp/meh 
==ShellType.サモナu
[tom@ideapad ~]$ grep -o '==ShellType.サモナ.*u' /tmp/meh
==ShellType.サモナu
[tom@ideapad ~]$ grep -o '==ShellType.サモナ.u' /tmp/meh
==ShellType.サモナu

Обратите внимание, что я использую одинарные кавычки, так как с , двойные кавычки могут еще больше усложнить задачу. Правильный способ выполнить желаемую grep:

[tom@ideapad ~]$ grep -o '==ShellType.サモナ\u' /tmp/meh 
==ShellType.サモナu
[tom@ideapad ~]$ grep -o "==ShellType\.サモナ\\u" /tmp/meh 
==ShellType.サモナu

Насколько я знаю, grep не считает u30FC (однако в дальнейшем экранированный), чтобы быть символом Юникода, например printf в оболочке делает. Чтобы на самом деле grep one с его кодовой точкой, вы можете заставить оболочку сначала расширить его с помощью цитирования ANSI-C (хотя это может не работать в каждой оболочке POSIX):

[tom@ideapad ~]$ printf 'u30FC' > /tmp/heh
[tom@ideapad ~]$ grep $'u30FC' /tmp/heh 
ー

PS Возможно, стоит упомянуть, что, хотя цитирование ANSI-C использует одинарные кавычки в своем синтаксисе, это НЕ означает, что оно работает как одинарные кавычки для частей, кроме расширения кодовой точки:

[tom@ideapad ~]$ grep -o $'==ShellType.サモナ\u' /tmp/meh 
[tom@ideapad ~]$ grep -o $'==ShellType\.サモナ\\u' /tmp/meh 
==ShellType.サモナu

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *