如何在 Bash 中通過不同的程式碼點列印 ASCII 字元?
在 ASCII 表中,存在“J”字元,它在不同的數字系統中有程式碼點:
Oct Dec Hex Char 112 74 4A J
可以通過列印
printf '\112'
或通過八進制程式碼點列印此字元echo $'\112'
。如何通過十進制和十六進制程式碼點表示列印相同的字元?
十六進制:
printf '\x4a'
十二月:
printf "\\$(printf %o 74)"
十六進制的替代品:-)
xxd -r <<<'0 4a'
一般來說,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")" 🐮
注意:對於 4.3 之前的 bash(在該版本及更高版本中已更正),UNICODE 方式存在問題,UNICODE 點 128 和 255(十進制)之間的字元可能列印不正確。
參考
PARAMETERS
裡面的第四段man bash
:如果變數具有其整數屬性集,則即使不使用 $((…)) 擴展,也會將 value 評估為算術表達式(請參閱下面的算術擴展)。
在“算術評估”中
man bash
:以 0 開頭的常量被解釋為八進制數。前導 0x 或 0X 表示十六進制。否則,數字採用形式
$$ base# $$n,其中可選基數是 2 到 64 之間的十進制數,表示算術基數,n 是該基數中的數字。如果省略 base#,則使用基數 10。大於 9 的數字依次用小寫字母、大寫字母、@ 和 _ 表示。如果 base 小於或等於 36,則可以互換使用小寫和大寫字母來表示 10 到 35 之間的數字。