如何在 Bash 中透過不同的代碼點列印 ASCII 字元?

如何在 Bash 中透過不同的代碼點列印 ASCII 字元?

在 ASCII 表中,存在“J”字符,它在不同的數字系統中具有代碼點:

Oct   Dec   Hex   Char
112   74    4A    J

可以透過列印 printf '\112'或 來透過八進位代碼點列印此字元echo $'\112'。如何透過十進制和十六進位代碼點表示列印相同的字元?

答案1

十六進位:

printf '\x4a'

十二月:

printf "\\$(printf %o 74)"

十六進制的替代方法:-)

xxd -r <<<'0 4a'

答案2

一般來說,shell 可以理解變數中的十六進制、八進制和十進制數字,只要它們被定義為integers

$ declare -i v1 v2 v3 v4 v5 v6 v7
$ v1=0112
$ v2=74
$ v3=0x4a
$ v4=8#112
$ v5=10#74
$ v6=16#4a
$ v7=18#gg
echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

或者它們是「算術擴展」的結果:

$ : $(( v1=0112, v2=74, v3=0x4a, v4=8#112, v5=10#74, v6=16#4a, v7=18#gg ))
$ echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

因此,您只需要一種方法來列印屬於變數值的字元。
但這裡有兩種可能的方法:

$ var=$((0x65))
$ printf '%b\n' "\\$(printf '0%o' "$var")"
e

$ declare -i var
$ var=0x65; printf '%b\n' "\U$(printf '%08x' "$var")"
e

需要兩個 printf,一個將值轉換為十六進位字串,第二個實際列印字元。

第二個將列印任何 UNICODE 點(如果您的控制台設定正確)。
例如:

$ var=0x2603; printf '%b\n' "\U$(printf '%08x' "$var")"

一個雪人。

具有 utf-8 表示形式的字元f0 9f 90 ae如下0x1F42E。搜尋cow face site:fileformat.info得到它:

$ var=0x1F42F; printf '%b\n' "\U$(printf '%08x' "$var")"

答案3

十進制:

chr() {
    local c
    for c
    do
        printf "\\$((c/64*100+c%64/8*10+c%8))"
    done
}

chr 74

十六進位:

chr $((16#4a))

此函數可以執行序列:

$ chr 74 75 76; echo
JKL
$

答案4

如果您有要轉換的數字列表,並且希望避免函數呼叫並為每個字元建立子shell,則可以預先定義 ascii 集:

ascii=$(for x in {0..9} {A..F}; do for y in {0..9} {A..F}; do echo -ne "\x$x$y"; done; done)

請注意,空字元被排除在外,因此每個字元都會偏移 1。

然後使用類似這樣的內容(假設每行 1 個數字):

while read c; do out+="${ascii:$c-1:1}"; done <<< "$in"
echo "$out"

相關內容