使用sed替换十六进制字符串

28

我在使用sed进行十六进制字符的查找和替换时遇到了一些问题。我想要替换文件中所有出现的以下十六进制字符串:

0x0D4D5348

使用以下十六进制字符串:

0x0D0A4D5348

我该怎么做?

编辑:我正在尝试进行十六进制查找/替换。输入文件中没有字面值“0x0D4D5348”,但它确实在其中具有该ASCII表示。

3个回答

40

GNU sed v3.02.80、GNU sed v1.03和HHsed v1.5 by Howard Helman都支持符号\xNN,其中“NN”是两个有效的十六进制数,00-FF。

以下是如何替换二进制文件中的十六进制序列:

$ sed 's/\x0D\x4D\x53\x48/\x0D\x0A\x4D\x53\x48/g' file > temp; rm file; mv temp file

如@sputnik指出,您可以使用sed的原地功能。但有一个注意点,如果您在OS/X上使用它,您需要添加一组空引号:
$ sed '' 's/\x0D\x4D\x53\x48/\x0D\x0A\x4D\x53\x48/g' file

在 OS/X 上,使用 in place 命令进行替换时需要传递一个参数以指示在进行备份时要添加的文件扩展名,因为它首先会创建临时文件。但是...OS/X 的sed 不支持\x


我感謝詳細的回復,但我想我表達得不夠清楚。我想基本上用 0x0D0A 替換行尾的 0x0D,但我只想替換下一行開頭包含字符 "MSH"(十六進制為 0x4D5348)的行尾。這樣說明清楚了嗎? - Carter
最好编辑您的原始消息,而不是期望其他读者阅读所有评论,寻找您修订后的规范。祝好运! - shellter
谢谢你的建议。问题已经修改了。 - Carter
添加了一个关于二进制值的注释。 - tolitius
请考虑修改您的答案,使用sed -i而不是> tmp; rm file..business。 - ScottZ
6
由于OS X中的sed不支持\x,是否有其他方法可以在OS X中实现此操作? - Ernest

5

这对于我在Linux和OSX上的使用是有效的。

原地替换:

sed -i '.bk' 's'/`printf "\x03"`'/foo/g' index.html

(请参考@tolitius的回答中@Ernest的评论)

2
古老是一个相对的概念...这对我很有帮助,谢谢。 - ojblass

5
在OS/X系统的Bash中,您可以使用如下命令:
# this command will crate a variable named a which contains '\r\n' in it
a=`echo -e "hello\r\nworld\r\nthe third line\r\n"`

echo "$a" | sed $'s/\r//g' | od -c


现在你可以看到输出的字符:
0000000    h   e   l   l   o  \n   w   o   r   l   d  \n   t   h   e
0000020    t   h   i   r   d       l   i   n   e  \n
0000033

您需要注意's/\r//g'$'s/\r//g'之间的区别。 基于上述实践,您可以使用类似这样的命令替换十六进制字符串。

echo "$a" | sed $'s/\x0d//g'  | od -c

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