sed中的十六进制代码 - 在OSX上表现不尽如人意

时间:2013-02-15 05:48:36

标签: macos sed hex

我的问题的答案可能存在于SO,但我老老实实地看起来很难找到它。我得到的最接近的是this Q&A,但我无法在我的机器上重现结果(OSX 10.7.5,使用bash)。

以下是问题的重要性:我无法将sed解释为\xnn(例如\x41 A)作为十六进制字符。特别让我疯狂的是:

echo -e '\x41' 

结果为A - 因此操作系统及其功能理解我的十六进制代码......

echo -e '\x41' | sed 's/A/B/'

结果为B - 正如预期的那样,因为在A看到它之前,十六进制代码已转换为sed

但是

echo A | sed 's/\x41/B/'

结果为A - 我原本期望B

我尝试过像

这样的事情
echo A | LANG='C' sed 's/\x41/B/'

结果为A

echo A | LANG='' sed 's/\x41/B/'

...同上

echo A | sed 's/[\x41]/B/'

结果为A

但是...

echo A | sed 's/[\x41-\x41]/B/'

导致B ???

我是完全愚蠢的吗?或sed真的有些奇怪吗?它显然可以解释范围内的十六进制代码,但我无法将其解释为单个字符。我错过了什么?

请注意 - 我正在寻找能够解释为什么上述行为方式的答案,以及如何在{{1 OSX平台上的字符串, 。这意味着在{search}和sed命令的“替换”部分。因为我显然已经显示我可以用[\ xnn- \ xnn]搜索单个字符;这不是我要找的答案。

提前致谢!

2 个答案:

答案 0 :(得分:11)

没有关于“操作系统及其功能理解”的一般概念 - 每个程序,功能等都能理解它自己特定的元字符集,转义等等。而sed不会发生这种情况。做十六进制代码。但是bash确实(如果你问的话),所以你可以在用sed调用$''之前让它翻译一下:

$ echo A | sed $'s/\x41/B/'
B

请注意,这也会在将其传递给sed之前解释其他转义序列,因此如果要将任何转义传递给sed,则需要对它们进行双重转义,或者只切换引用模式相关部分位于$''

$ echo A | sed $'s/\\(\x41\\)/B\\1/' # double-escapes for sed's escape sequences
BA
$ echo A | sed 's/\('$'\x41''\)/B\1/' # equivalent with different quote modes
BA
$ echo A | sed 's/\(A\)/B\1/' # simplest equivalent version
BA

如果你想在变量而不是常量字符串中解释十六进制转义,那么你几乎必须使用shell的printf内置:

$ hex=41
$ echo A | sed "s/$(printf "\x$hex")/B/"
B

答案 1 :(得分:3)

@GordonDavisson给了我灵感,尝试了两件事......

首先 - 我突然想知道我是否误解了

的输出
echo A | sed 's/[\x41-\x41]/B/'

我认为这意味着sed了解范围内的\xnn代码,但我错了。我试过的时候

echo A | sed 's/[\x40-\x40]/B/'

仍然得到B的输出,但我认为我不再包括A\x41)。很明显,sed正在以我预期的其他方式解释我的范围。通过更仔细地查看man re_format页面解决了这个问题。它说

  

[...]所有其他特殊字符,包括“\”,都会失去特殊性   括号表达式中的重要性。

但后来我得到了灵感:如果echo -e可以扩展字符串,也许我可以用它来提供我想要的字符串sed ......

echo "This?" | sed `echo -e 's/\x54\x68\x69\x73\x3F/\x59\x65\x73\x21/'`

制作Yes!

echo "That?" | sed `echo -e 's/\x54\x68\x69\x73\x3F/\x59\x65\x73\x21/'`

制作That?

当然在这种情况下,\xnn字符只表示纯ASCII - 解码字符串只是给's/This?/Yes!/',但它确实建立了将十六进制字符插入sed字符串的原则。唯一没有帮助澄清的是“如果你的echo语句打印出需要在sed中转义的字符会发生什么。而且它仍然没有解决我的基本问题 - ”如何插入hex字符直接放入sed字符串。我仍然怀疑它是可能的......在阅读sed(声称使用“旧的”正则表达式,尽管-E标志可以使其使用“扩展”表达式,并指示用户访问re_format手册页以获取详细信息;以及re_syntax页面,由re_format引用。在这些页面之间,确实看起来像添加十六进制字符串应该直接工作...

我将此信息添加为“回答”而不是“编辑”我的问题,因为我相信开始回答我的问题...期待发表评论!