sed regexp 十六进制字符

Bab*_*aba 3 sed regular-expression

我有以下字符串

echo -e "a12\x8fb12\x9f" | xxd
0000000: 6131 328f 6231 329f 0a                   a12.b12..
Run Code Online (Sandbox Code Playgroud)

并想删除序列12\x9f12\x8f使用sed.

我可以用这个命令来做

sed -e 's_12\x8f__g' -e 's_12\x9f__g'
Run Code Online (Sandbox Code Playgroud)

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

sed -e 's_12[\x8f\x9f]__g'
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 8

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

例如:

sed 's/[eé\xa9]//'
Run Code Online (Sandbox Code Playgroud)

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

要将任意字节数据与文本实用程序(如 )匹配sed,您需要使用字符为字节的语言环境,这是LC_ALL=C.

LC_ALL=C sed 's/12[\x8f\x9f]//g'
Run Code Online (Sandbox Code Playgroud)

或者便携:

LC_ALL=C sed "$(printf 's/12[\217\237]//g')"
Run Code Online (Sandbox Code Playgroud)

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