我的问题的答案可能存在于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]搜索单个字符;这不是我要找的答案。
提前致谢!
答案 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
引用。在这些页面之间,确实看起来像添加十六进制字符串应该直接工作...
我将此信息添加为“回答”而不是“编辑”我的问题,因为我相信开始回答我的问题...期待发表评论!