我的问题的答案可能存在于SO,但我老老实实地看起来很难找到它.我得到的最接近的是这个问答,但我无法在我的机器上重现他们的结果(OSX 10.7.5,使用bash).
这是减少到其本质问题:我无法sed解释\xnn(例如\x41用于A)为十六进制字符.特别让我疯狂的是:
echo -e '\x41'
Run Code Online (Sandbox Code Playgroud)
结果A- 所以操作系统及其功能理解我的十六进制代码......
echo -e '\x41' | sed 's/A/B/'
Run Code Online (Sandbox Code Playgroud)
结果B- 正如所料,因为十六进制代码转换为A之前sed看到它
但
echo A | sed 's/\x41/B/'
Run Code Online (Sandbox Code Playgroud)
结果A- 我原以为B
我尝试过类似的东西
echo A | LANG='C' sed 's/\x41/B/'
Run Code Online (Sandbox Code Playgroud)
结果是 A
echo A | LANG='' sed 's/\x41/B/'
Run Code Online (Sandbox Code Playgroud)
同上...
echo A | sed 's/[\x41]/B/'
Run Code Online (Sandbox Code Playgroud)
结果是 A
但...
echo A | sed 's/[\x41-\x41]/B/'
Run Code Online (Sandbox Code Playgroud)
结果B???
我完全是傻瓜吗?或者真的有什么奇怪的sed吗?它显然可以解释范围内的十六进制代码,但我无法将其解释为单个字符.我错过了什么?
请注意 - 我正在寻找答案,这些答案既解释了上述行为的原因,也解决了在OSX平台上将单个十六进制代码插入sed字符串中的任何位置的方法.这意味着在命令的"搜索"和"替换"部分.因为我显然已经显示我可以用[\ xnn-\xnn]搜索单个字符; 这不是我要找的答案.s/
提前致谢!
Gor*_*son 11
没有关于"操作系统及其功能理解"的一般概念 - 每个程序,功能等都能理解它自己特定的元字符集,转义等等.而且恰好sed不会发生十六进制代码.但是bash所做的(如果你问它),这样你就可以拥有它之前调用翻译他们sed用$'':
$ echo A | sed $'s/\x41/B/'
B
Run Code Online (Sandbox Code Playgroud)
请注意,这也会在传递它们之前解释其他转义序列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
Run Code Online (Sandbox Code Playgroud)
如果你想在变量而不是常量字符串中解释十六进制转义,那么你几乎必须使用shell的printf内置:
$ hex=41
$ echo A | sed "s/$(printf "\x$hex")/B/"
B
Run Code Online (Sandbox Code Playgroud)
@GordonDavisson 给了我尝试另外两件事的灵感......
首先 - 我突然想知道我是否误解了输出
echo A | sed 's/[\x41-\x41]/B/'
Run Code Online (Sandbox Code Playgroud)
我认为这意味着sed理解\xnn某个范围内的代码,但我错了。当我尝试
echo A | sed 's/[\x40-\x40]/B/'
Run Code Online (Sandbox Code Playgroud)
我仍然得到 的输出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/'`
Run Code Online (Sandbox Code Playgroud)
生产 Yes!
echo "That?" | sed `echo -e 's/\x54\x68\x69\x73\x3F/\x59\x65\x73\x21/'`
Run Code Online (Sandbox Code Playgroud)
生产 That?
当然,在这种情况下,\xnn字符仅表示对刚刚给出的字符串进行纯 ASCII 解码's/This?/Yes!/',但它确实建立了将十六进制字符插入到sed. 这不利于清理的唯一的事情就是“会发生什么,如果在转义你将需要echo语句打印字符sed,它仍然没有解决我的根本问题- ”我怎么插入的十六进制字符直接进入一个sed字符串. 我仍然怀疑这是可能的......在阅读了sed(声称使用“旧”正则表达式,尽管 -E 标志可以使它使用“扩展”表达式,并将用户引导到re_format手册页)的文档后更是如此有关详细信息;以及re_syntax引用的页面re_format. 在这些之间,它确实看起来像添加一个十六进制字符串应该直接工作......
我将此信息作为“答案”而不是“编辑”添加到我的问题中,因为我相信它开始回答我的问题......期待评论!
| 归档时间: |
|
| 查看次数: |
4060 次 |
| 最近记录: |