【问题标题】:sed - print translated HEX using capture groupsed - 使用捕获组打印翻译的十六进制
【发布时间】:2018-09-23 20:55:52
【问题描述】:

我想通过隔离捕获组中的 HEX 值来直接使用 sed 打印 HEX 值转换。这有效:

echo bbb3Accc | sed -n 's/3A/\x3A/p'
bbb:ccc

...但这不起作用:

echo bbb3Accc | sed 's/\(3A\)/\x\1/'
bbbx3Accc

...或基于 URL 编码字符串的实际捕获组 REGEX 匹配:

echo bbb%3Accc | sed 's/%\([A-Za-z0-9]\)/\x\1/'
bbbx3Accc

如果 HEX 值是由 REGEX 捕获组以及 \x 转义符构成的,那么显然 sed 不再解释和转换 HEX 值。

但我想知道是否有一种我不知道的解决方法,仅使用 sed。请注意,我知道我可以执行 bash 命令替换并将 sed 语法包装在 echo -e 中,但我想避免这种情况。

【问题讨论】:

  • \x\1 将导致 \x\1 (因为 \x 期望后面有两个十六进制数字,但 \appearing 将其切断)... \x 没有特殊意思是,所以只打印x...我认为在 sed 中没有任何方法可以做到这一点...您可以使用 perl...不确定 awk,但可能有 match/substr 的方法
  • 这与 (GNU) awk 的问题大致相同。这有效:awk 'BEGIN {printf "%c\n",0x3A}'(正确打印:)但这惨败echo 0x3A | awk '{printf "%c\n",$1}'
  • @linux_newbie 将非十进制字符串转换为您使用strtonum() 的awk 中的数字,例如:echo 0x3A | gawk '{printf "%c\n",strtonum($1)}' 输出:

标签: regex bash sed hex capture-group


【解决方案1】:

如 cmets 中所述,\xAB 由 sed 的解析器解释,而不是作为表达式,因此 \x 不会按照您尝试的方式工作。

sed 非常原始,您的示例超出了它的预期用途,因此您最好使用更通用的东西。例如,在 Perl 中:

$ echo bbb3Accc | perl -ple 's/([0-9A-F]{2})/chr(hex($1))/ge'
bbb:ccc

【讨论】:

  • 我明白了。它确实有效,但只有当我实际编写 HEX 代码时(根据我的示例),而不是通过 REGEX 捕获组放置它。令人惊讶的是(或者可能不是),awk 也是如此(查看我对第一条评论的回复)。
【解决方案2】:

您的问题不清楚,但也许这就是您尝试使用 GNU awk 进行多字符 RS、RT 和 strtonum() 的操作:

$ echo 'bbb%3Accc%21ddd' |
gawk -v RS='%[[:xdigit:]]{2}' 'sub(/%/,"0x",RT){RT=sprintf("%c",strtonum(RT))} {ORS=RT} 1'
bbb:ccc!ddd

【讨论】:

  • 感谢您的回复,这对我发布的示例很有帮助。但是我想用 sed 做的原因是在给定的行上执行多个替换并打印所有内容,bbb%3Accc%21ddd 会产生bbb:ccc!ddd 等行。到目前为止,最简单的方法是做一个echo -e 中的 sed 命令替换
  • 在 shell 编程中,“简单”通常意味着“简短和错误”,因此 YMMV 与 echo+sed 组合相比在 awk 中稳健地执行。只需真正想想您的要求以及您心目中的脚本正在做什么。我根据您更新的要求和示例更新了我的答案。
  • 谢谢,真的没想到用RS+RT。
猜你喜欢
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多