【发布时间】:2017-03-16 13:09:44
【问题描述】:
我有一组有效字符 [0-9a-zA-Z] 和一个分配了其中一个字符的变量。我想要做的是能够将该变量递减到集合中的下一个。
我不知道如何减少字母,它只适用于数字。
#!/bin/bash
test=b
echo $test # this shows 'b'
let test-=1
echo $test # I want it to be 'a'
【问题讨论】:
我有一组有效字符 [0-9a-zA-Z] 和一个分配了其中一个字符的变量。我想要做的是能够将该变量递减到集合中的下一个。
我不知道如何减少字母,它只适用于数字。
#!/bin/bash
test=b
echo $test # this shows 'b'
let test-=1
echo $test # I want it to be 'a'
【问题讨论】:
优势
test=$(tr 1-9a-zA-Z 0-9a-zA-Y <<<"$test")
它是否正确(我认为)将a 减少到9 和A 减少到z。如果这不是您想要的顺序,也很容易调整。
详情请参阅 man tr。这是tr的Gnu版本; Posix 不保证字符范围,但大多数tr 实现都有它们。 <<<“这里的字符串”也是常用的扩展,bash 实现的。
【讨论】:
ba翻译成a9
$ 不变。 OP 说他有一个“包含这些字符中的 一个”的变量,所以我想我已经回答了被问到的问题。 (我对字符串 ase 有类似的答案,所以请随时提出不同的问题。
test=$(printf "\\$(printf '%03o' "$(($(printf '%d' "'$test") - 1 ))")")
【讨论】:
A 开头,则结果将为 @
你可以试试这个:
#!/bin/bash
test=b
if [[ $test == A || $test == a || $test == 0 ]]
then
echo "character already at lowest value"
else
# convert $test to decimal digit
test_digit=$(printf '%d' "'$test")
decremented=$(( test_digit - 1 ))
# print $decremented as a char
printf "\\$(printf '%03o' "$decremented")\n"
fi
【讨论】:
A 的ascii 值(例如)减少为@ 的ascii 值,它不在提供的列表中:0-9a-zA-Z。
如果我们为整个字符串设置一个变量(比如a):
$ a=$( IFS=''; set -- {0..9} {a..z} {A..Z}; echo "$*"); echo "$a"
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
我们可以利用 bash“算术”可以使用最多 62 的基数(与显示的字母顺序相同)这一事实。
$ test="A"; echo "${a:$((62#$test-1)):1}"
z
这仅适用于“一个字符”(而不是零 0)。
它可能会扩展到几个字符,但这不是被要求的。
【讨论】: