我正在使用awk
urldecode 一些文本。
如果我将字符串编码到printf
语句中,就像printf "%s", "\x3D"
它正确输出一样=
。如果我将整个转义字符串作为变量,则相同。
但是,如果我只有 ,我3D
怎么能附加\x
soprintf
会打印=
而不是\x3D
?
我正在使用busybox awk 1.4.2
和ash
外壳。
我不知道你是如何在 awk 中做到这一点的,但这在 perl 中是微不足道的:
echo "http://example.com/?q=foo%3Dbar" |
perl -pe 's/\+/ /g; s/%([0-9a-f]{2})/chr(hex($1))/eig'
由于您使用的是 ash 而 Perl 不可用,我假设您可能没有gawk
.
对我来说,使用gawk
或busybox awk,您的第二个示例与第一个示例的工作方式相同(我从两者都得到“=”),除非我使用该--posix
选项(在这种情况下,我得到两个“x3D” )。
如果我使用--non-decimal-data
or --traditional
withgawk
我得到“=”。
您使用的是哪个版本的 AWK(awk
、nawk
、gawk
、busybox - 和版本号)?
编辑:
您可以通过添加零将变量的字符串值强制为数字一:
~/busybox/awk 'BEGIN { string="3D"; pre="0x"; hex=pre string; printf "%c", hex+0}'
GNU awk
#!/usr/bin/awk -fn
@include "ord"
BEGIN {
RS = "%.."
}
{
printf RT ? $0 chr("0x" substr(RT, 2)) : $0
}
或者
#!/bin/sh
awk -niord '{printf RT?$0chr("0x"substr(RT,2)):$0}' RS=%..
这依赖于 gnu awk 对 split 函数的扩展,但这有效:
gawk '{ numElems = split($0, arr, /%../, seps);
outStr = ""
for (i = 1; i <= numElems - 1; i++) {
outStr = outStr arr[i]
outStr = outStr sprintf("%c", strtonum("0x" substr(seps[i],2)))
}
outStr = outStr arr[i]
print outStr
}'
首先,我知道这是一个老问题,但没有一个答案对我有用(仅限于busybox awk)
两种选择。解析标准输入:
awk '{for (y=0;y<127;y++) if (y!=37) gsub(sprintf("%%%02x|%%%02X",y,y), y==38 ? "\\&" : sprintf("%c", y));gsub(/%25/, "%");print}'
获取命令行参数:
awk 'BEGIN {for (y=0;y<127;y++) if (y!=37) gsub(sprintf("%%%02x|%%%02X",y,y), y==38 ? "\\&" : sprintf("%c", y), ARGV[1]);gsub(/%25/, "%", ARGV[1]);print ARGV[1]}' parameter
必须最后做 %25 因为否则像 %253D 这样的字符串会被双重解析,这不应该发生。
y==38 的内联检查是因为 gsub 将 & 视为特殊字符,除非您使用反斜杠。