188*_*885 7 linux bash ascii printf
我用下面要转换INT至炭和焦炭到INT在bash。但我不明白如何printf \\$(printf '%03o' $1)
或printf '%d' "'$1"
工作。请解释如何 printf \\$(printf '%03o' $1)
和printf '%d'
工作。
#!/bin/bash
# chr() - converts decimal value to its ASCII character representation
# ord() - converts ASCII character to its decimal value
chr() {
printf \\$(printf '%03o' $1)
}
ord() {
printf '%d' "'$1"
}
ord A
echo
chr 65
echo
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 10
printf '\101'
其中101
是一个八进制数,输出具有该值的字节。
当发送到ASCII终端,将被呈现为A
如A
在ASCII字符65(八进制101)和所有兼容ASCII字符集(其包括与EBCDIC那些在某些IBM系统仍然使用之外最现代化的字符集)。
在
printf \\$(printf '%03o' $1)
Run Code Online (Sandbox Code Playgroud)
应该是这样写的:
printf "\\$(printf '%03o' "$1")"
Run Code Online (Sandbox Code Playgroud)
作为离开参数扩展(如$1
),或命令替换($(...)
)未加引号是 Bourne-like shell 中的 split+glob 运算符,这里不需要
printf '%03o' "$1"
将数字转换$1
为 3 位八进制数printf "\\$(...)"
将该八进制附加到 a \
(\\
双引号内变为\
)并将其传递给printf
以便输出相应的字节值。请注意,它仅适用于字符集为每个字符一个字节的区域设置(如iso8859-1
),或者,在具有多字节字符集的区域设置中,仅适用于值 0 到 127。
在bash
,
printf '%d\n' "'A"
Run Code Online (Sandbox Code Playgroud)
打印字符的 Unicode 代码点A
(或至少mbtowc()
在 GNU 系统上返回的值至少是 Unicode 代码点)。
其他一些实现(包括独立的 GNUprintf
实用程序)会返回字符的第一个字节的值。
对于 ASCII 字符A
和基于 ASCII 的系统,这没有任何区别,但对于其他人来说很重要。例如,希腊?
字符 (U+03B1) 被编码为:
Bashprintf '%d\n' "'?"
将始终输出945
(十六进制为 0x03b1),这是 Unicode 代码点,?
与语言环境无关(至少在 GNU 系统上),但其他人可能会根据语言环境返回 225、206 或 166。
您可以从中看到,对于 ASCII 字符(或值 0 到 127),或者在使用所有字符(值 0 到 255)的字符集的语言环境中,这些chr
和ord
只是彼此相反iso8859-1
。
如果ord()
要返回 Unicode 代码点,则相反(打印与 Unicode 代码点对应的字符)将是:
chr() {
printf "\U$(printf %08X "$1")"
}
Run Code Online (Sandbox Code Playgroud)
(假设bash
4.3 或更高版本(\UXXXXXXXX
在 4.2 中添加,但在 4.3 之前无法对字符 U+0080 到 U+00FF 正常工作))。
然后,在任何语言环境中:
$ ord ?
945
$ chr 945
?
Run Code Online (Sandbox Code Playgroud)
或者ord()
返回给定字符编码的字节值(在当前语言环境中):
ord() {
printf %s "$1" | od -An -vtu1
}
Run Code Online (Sandbox Code Playgroud)
并chr()
输出这些字节:
chr() {
printf "$(printf '\\%o' "$@")"
}
Run Code Online (Sandbox Code Playgroud)
然后,例如在 UTF-8 语言环境中:
$ ord ?
206 177
$ chr 206 177
?
Run Code Online (Sandbox Code Playgroud)
(你ord ?
会给945,你chr
会为这两个垃圾chr 945
和chr 206 177
)。
或者在语言环境中使用iso8859-7
:
$ ord ?
225
$ chr 225
?
Run Code Online (Sandbox Code Playgroud)
(您ord ?
将给出 945,但如果在 GNU 系统上printf
用/usr/bin/printf
if替换,则可能给出 225 )。
内部printf '%03o' $1
返回值$1
(即 65)作为八进制值(65 -> 101)。
外部printf \\$(..)
打印八进制值表示的字符。
见man printf
行:
\NNN 字节,八进制值 NNN(1 到 3 位数字)
因为printf '%d' "'$1"
您需要指定'
以指示$1
应将其视为单个字符常量,否则 printf 会引发错误,指示该值是无效数字。然后使用字符常量的值printf
以十进制格式打印"%d"