我有以下字符串
echo -e "a12\x8fb12\x9f" | xxd
0000000: 6131 328f 6231 329f 0a a12.b12..
并想要删除序列12\x9f
和12\x8f
。sed
我可以用这个命令做到这一点
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
在这种情况下请使用。