![使用 printf 输出给定一些 ASCII 数字的字符](https://linux22.com/image/189839/%E4%BD%BF%E7%94%A8%20printf%20%E8%BE%93%E5%87%BA%E7%BB%99%E5%AE%9A%E4%B8%80%E4%BA%9B%20ASCII%20%E6%95%B0%E5%AD%97%E7%9A%84%E5%AD%97%E7%AC%A6.png)
我一直在尝试输出printf
一些字符,给出它们的 ASCII 数字(十六进制)...如下所示:
#!/bin/bash
hexchars () { printf '\x%s' $@ ;}
hexchars 48 65 6c 6c 6f
Expected output:
Hello
由于某种原因,这不起作用。有任何想法吗?
编辑:
根据 Isaac 提供的答案(已接受的答案),我最终得到了这个函数:
chr () { local var ; printf -v var '\\x%x' $@ ; printf "$var" ;}
请注意,我稍微重写了他的答案,以便通过避免子 shell 来提高速度。
Result:
~# chr 0x48 0x65 0x6c 0x6c 0x6f
Hello
~# chr 72 101 108 108 111
Hello
~# chr {32..126}
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}
我猜这个函数的反函数chr
会是这样的函数......
asc () { printf '%d\n' "'$1" ;}
asc A
65
chr 65
A
或者,如果我们想要严格的十六进制变体......
chrx () { local var ; printf -v var '\\x%s' $@ ; printf "$var\n" ;}
ascx () { printf '%x\n' "'$1" ;}
chrx 48 65 6c 6c 6f
Hello
ascx A
41
谢谢你!
答案1
哦,当然,只是必须分两步完成。就像两步探戈一样:
$ printf "$(printf '\\x%s' 48 65 6c 6c 6f)"; echo
Hello
或者,另一种选择:
$ test () { printf "$(printf '\\x%s' "$@")"; echo; }
$ test 48 65 6c 6c 6f
Hello
或者,为了避免打印“无参数”:
$ test () { [ "$#" -gt 0 ] && printf "$(printf '\\x%s' "$@")"; echo; }
$ test 48 65 6c 6c 6f
Hello
$
假设参数是 1 到 127 之间的十进制值(空参数会被计算在内,但打印时会失败)。
答案2
\x
需要跟随一个文字十六进制值:
$ printf '\x48\n'
H
$ c=48
$ printf '\x%s\n' "$c"
bash: printf: missing hex digit for \x
\x48
据推测,这是因为printf
在使用结果字符串作为格式之前,将扩展格式字符串中的任何十六进制文字作为单独的步骤。
你可以做什么:
unhexlify() {
for character
do
format="\x${character}"
printf "$format"
done
printf '\n'
}
测试:
$ unhexlify 48 65 6c 6c 6f
Hello
答案3
使用珀尔它的pack
功能是我们打包两个十六进制数字并打印 ASCII 表示形式。
charx() {
perl -le 'print pack "(H2)*", @ARGV' -- "$@"
}
我们使用桌面计算器直流电输入基数 16 并使用以下命令以 ASCII 字符打印出来A命令。
charx() {
dc <<eof
16i
$(echo "$@" | tr a-f A-F)
[SAz0<a]sa
[LAanln1-dsn0<b]sb
[zsnlaxlbxAan]sc
z0<c
eof
}
用作:
charx 48 65 6c 6c 6f
结果
Hello