为什么sed无法替换二进制文件中的0x24字节?

6

我想要将二进制文件中的某些字节替换为其他字节。通过以下方式创建了一个示例文件(长度为6个字节)

echo -ne '\x8f\x15\x42\x02\x24\xc2' > test

然后尝试通过sed替换字节\x15\x42\x02\x12\x12\x02

sed 's \x15\x42\x02 \x12\x12\x02 g' test > test1

sed替换字节:

cat test test1 | xxd -c 6
0000000: 8f15 4202 24c2  ..B.$.
0000006: 8f12 1202 24c2  ....$.
           ^^ ^^^^

尝试将字节\x42\x02\x24替换为\x12\x02\x24
sed 's \x42\x02\x24 \x12\x02\x24 g' test > test2

sed未替换的字节:

cat test test2 | xxd -c 6
0000000: 8f15 4202 24c2  ..B.$.
0000006: 8f15 4202 24c2  ..B.$.
              ^^^^ ^^

有什么问题吗?我使用的是sed (GNU sed) 4.2.2 (Kubuntu 13.10)

谢谢。


我想知道这是否是因为\x24是$,它是一个正则表达式特殊字符(行锚定符),而序列\x42\x02没有出现在行末。 - glenn jackman
我已经进行了一些实验,尝试了各种长度的不同替换,我认为格伦是正确的。 - Eric Smith
无论如何,sed 并不适用于二进制替换。您将遇到多字节字符等问题。最好使用 bbe 来代替,这是一种类似于“sed 用于二进制文件”的工具。 - Philippos
3个回答

9
这是因为0x24是美元符号$的十六进制代码。请注意,在正则表达式中(sed用于匹配),^$具有特殊含义,分别表示“行首”和“行尾”。除非转义,否则这些字符将被忽略。因此,

echo "this and that" | sed 's/this$/cat/'

将保持字符串不变,因为您要求sed在行末查找“this”--由于“that”在行末,它不匹配。然而,

echo "It costs $50.00." | sed 's/\$50\.00/47.00 Swiss Francs/'

会按预期更改该行,因为$已被转义。对于二进制数据,只需在正则表达式部分中的\x24之前包括反斜杠字符\的十六进制代码\x5c即可。

干杯。


4
你可以尝试这个:
hexdump -ve '1/1 "%.2X"' file1 | sed 's/420224/121224/g' | xxd -r -p > new_updated

测试:

sat:~# xxd -c 6  file1
0000000: 8f15 4202 24c2  ..B.$.
sat:~# hexdump -ve '1/1 "%.2X"' file1 | sed 's/420224/121224/g' | xxd -r -p > new_updated
sat:~# xxd -c 6 new_updated
0000000: 8f15 1212 24c2  ....$.

谢谢,但我很感兴趣,为什么sed可以替换某些字节序列,却无法替换文件中明确存在的另一些字节序列。毫不含糊 - 我已直接从echo命令复制粘贴字节到sed命令中。 - S-trace

1
sed语句应该如下所示。
sed 's/\x15\x42\x02/\x12\x12\x02/g' test > test1

搜索模式和替换模式之间应该有 / 符号。

结果应该如下所示。

[root@localhost ~]# cat test test1 | xxd -c 6       
0000000: 8f15 4202 24c2  ..B.$.
0000006: 8f12 1202 24c2  ....$.

它与空格作为命令/正则表达式分隔符一样工作 - 仍然替换\x15\x42\x02,但不替换\x42\x02\x24。 - S-trace
它可以工作,但你需要传递8而不是6给xdd,试一下并确认。 - Saddam Abu Ghaida
sed 's/\x42\x02\x24/\x12\x02\x24/g' test > test4 ; md5sum test test4 d1c66101d794687bf5d61b5ae4b7da03 test d1c66101d794687bf5d61b5ae4b7da03 test4 - 没有运气,xxd只是用来可视化更改的 - S-trace
你使用的是什么操作系统?我正在使用Kubuntu 13.10 AMD64,/bin/sed的md5sum为081c50c87d36bd90dadfb4df9483cacd。http://pastebin.com/wAMji5g7 - S-trace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接