如何grep
在 Linux 中查找 Unicode 字符‘零宽度空间’(U+200B)?
$ grep '%U200B' filename?
答案1
首先,让我们打印一个:
$ printf %b '\u200b' | uniname
character byte UTF-32 encoded as glyph name
0 0 00200B E2 80 8B ZERO WIDTH SPACE
命令uniname
是Unicode 实用程序。
现在我们应该能够使用相同的格式来搜索它(使用 Bash):
$ printf %b '\u200b' | grep -q "$(printf %b '\u200b')"
$ echo $?
0
这里的诀窍是printf %b
将参数视为编码字符,因此您可以使用\x
来打印单字节字符,使用\u
* 来打印多字节字符。
要在文件中找到它,只需执行以下操作:
grep "$(printf %b '\u200b')" filename
* POSIX 规范实际上并没有明确说明其%b
工作原理。该printf
页面称“%b 转换规范 [...] 已在此处添加,作为一种可移植的方式来处理 echo 实用程序提供的字符串操作数中扩展的 -escapes”,并且这一echo
页显示了一个未记录的使用示例。
测试:
$ printf %b '\u200b' > test.txt
$ grep -q "$(printf %b '\u200b')" test.txt
$ echo $?
0
答案2
以下操作正常。我使用 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
注意文件中字符“e2808b”的utf8编码。
这个简单的 grep 找到了正确的行:
> grep $'\u200b' testout.txt
4
> grep $'\u200b' testout.txt|hexdump -C
00000000 34 20 e2 80 8b 0a |4 ....|
00000006
值得一提的是,我的 GREP_OPTIONS 设置为:“--color=auto -I -D skip -d skip”,但我认为它们都不相关。
答案3
您还可以将 Perl 正则表达式与 GNU grep 一起使用
grep --perl-regexp '\x{200B}' 文件名
比较macos
棘手,因为自带的 BSD grep 不支持多字节。不过,GNU grep 可以通过 Homebrew 安装,在 Homebrew 中以 的形式提供ggrep
。