sed 正则表达式 十六进制字符

sed 正则表达式 十六进制字符

我有以下字符串

echo -e "a12\x8fb12\x9f" | xxd
0000000: 6131 328f 6231 329f 0a                   a12.b12..

并想要删除序列12\x9f12\x8fsed

我可以用这个命令做到这一点

sed -e 's_12\x8f__g' -e 's_12\x9f__g'

但为什么这个命令不起作用呢?

sed -e 's_12[\x8f\x9f]__g'

答案1

那是因为[...]角色匹配。sed将尝试根据 中指定的范围匹配字符[...]。在 UTF-8 语言环境中,您只能遇到\x8f作为多字节字符的一部分。您会注意到它.也不匹配(这是 POSIX 要求)。

例如:

sed 's/[eé\xa9]//'

没有意义。é是一个字符(编码为0xc3 0xa9),0xa9 不是一个字符而是一个字节,可以在字符内部找到(如é),e是一个字符(编码为 0x65)。您不能指望sed能够以某种方式匹配字符内和字节中的 0xa9。

将任意字节数据与文本像这样的实用程序sed,您将需要使用字符为字节的语言环境,这是典型的情况LC_ALL=C

LC_ALL=C sed 's/12[\x8f\x9f]//g'

或者便携式:

LC_ALL=C sed "$(printf 's/12[\217\237]//g')"

请注意,您不能期望使用sed.perl -p/-n在这种情况下请使用。

相关内容