将序数映射到 shell 脚本中的字母表

Arc*_*her 7 shell-script

是否有任何简单的解决方案可以在 shell 脚本中将序数(如 1、2、3、...)映射到字母 a、b、c?

Sté*_*las 11

在类似 Bourne 的 shell 中:

$ set a b c d e f g h i j k l m n o p q r s t u v w x y z
$ echo "$5"
e
Run Code Online (Sandbox Code Playgroud)

(对于ksh93,bash或 的最新版本zsh,您可以将该set行缩短为set {a..z}

或者:

$ awk 'BEGIN{printf("%c\n", 0x60 + 5)}'
e
Run Code Online (Sandbox Code Playgroud)

使用dc(至少 GNU dc)的一些实现:

$ echo 96 5 + P | dc
e
Run Code Online (Sandbox Code Playgroud)

使用zsh,您可以使用基数 36:

$ echo $(([##36] 9 + 5))
E
Run Code Online (Sandbox Code Playgroud)

或使用\0ooo八进制序列printf %b

$ printf '%b\n' "\0$(([##8]0x60 + 5))"
e
Run Code Online (Sandbox Code Playgroud)

对于非英语字母,假设使用 UTF-8 语言环境(此处为希腊语):

$ printf '%b\n' "\u$(([##16]0x3B0 + 5))"
?
Run Code Online (Sandbox Code Playgroud)

这是基于 Unicode 中的字符序列,无法保证该顺序与您所在地区的语言的常见字母顺序匹配,因此您最好手动硬编码完整的字符列表并使用第一种形式。

就像俄语字母表(根据维基百科):

$ set ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
$ echo "$5"
?
Run Code Online (Sandbox Code Playgroud)

这与 Unicode 顺序不完全匹配。

  • 对于带有数组和 {a..z} 扩展的 shell,如果您想避免破坏位置参数 $1、$2 等,但不介意创建一个新变量 `a=({a..z}); 回声 ${a[5]}` (5认同)
  • @JeffSchaller,这适用于`zsh`,但对于`ksh93` 或`bash`,你需要`a=('' {a..z})`(或`a=([1]=a {b.. z})` 仅使用 `bash`),因为 [这些 shell 与所有其他 shell 不同,它们的数组从索引 0 而不是 1 开始](/a/252405)。 (2认同)