使用 printf 输出给定一些 ASCII 数字的字符

使用 printf 输出给定一些 ASCII 数字的字符

我一直在尝试输出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

相关内容