bash - 增加包含字母的变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16823629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash - increment variables that contain letters
提问by Max Stevens
I have a set of valid characters [0-9a-z_] and a variable that is assigned one of these characters. What I want to do is to be able to increment that variable to the next in the set.
我有一组有效字符 [0-9a-z_] 和一个分配了这些字符的变量。我想要做的是能够将该变量增加到集合中的下一个。
If need be I can handle the "special" cases where it would increment from '9' to 'a' and 'z' to '_', but I can't figure out how to increment letters.
如果需要,我可以处理从“9”增加到“a”和“z”到“_”的“特殊”情况,但我不知道如何增加字母。
#!/bin/bash
y=b
echo $y # this shows 'b'
y=$((y+1))
echo $y # this shows '1', but I want it to be 'c'
回答by Gordon Davisson
y=b
echo "$y" # this shows 'b'
y=$(echo "$y" | tr "0-9a-z" "1-9a-z_")
echo "$y" # this shows 'c'
Note that this does not handle the case where $y = "_" (not sure what you want then, and in any case it'll probably require separate handling), and if $y is more than one character long it'll "increment" all of them (i.e. "10" -> "21", "09g" -> "1ah", etc).
请注意,这不能处理 $y = "_" 的情况(不确定您想要什么,并且在任何情况下都可能需要单独处理),如果 $y 的长度超过一个字符,它将“增加”所有这些(即“10”->“21”、“09g”->“1ah”等)。
回答by TrueY
Maybe this can be a solution:
也许这可以是一个解决方案:
a=({0..9} {a..z} _)
echo ${a[*]}
yc=11
echo ${a[yc]}
((++yc))
echo ${a[yc]}
echo ${a[++yc]}
#Alternative
declare -A h
# Fill the has point to the next character
for((i=0;((i+1))<${#a[*]};++i)) { h[${a[i]}]=${a[i+1]};}
y=b
echo $y, ${h[$y]}
Output:
输出:
0 1 2 3 4 5 6 7 8 9 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 _
b
c
d
b, c
回答by perreal
You can start with this:
你可以从这个开始:
echo 0x$(( $(printf "%x" "'b'") + 1)) | xxd -r
回答by rasty.g
for those who would like to print incremented letter by execution of a function:
对于那些想通过执行函数打印递增字母的人:
ALPHA=( {A..Z} )
alpha_increment () { echo ${ALPHA[${i:-0}]}; ((i++)) ;}
alpha_increment
A
alpha_increment
B
alpha_increment
C
回答by manoflinux
I wrote this for a project, it uses the chr and ord fucntions(also found here somewhere) and some pure bash(only external called in the function is tr), if you are doing more than 100 characters I would use something else, but for short strings in my testing its actually slightly faster than python. Also this script lower cases any input, you will have to modify it for upper case. after putting these functions in your script(or cut and paste into a shell) you can just do
我为一个项目写了这个,它使用 chr 和 ord 功能(也可以在这里找到)和一些纯 bash(函数中只有外部调用的是 tr),如果你做的字符超过 100 个,我会使用别的东西,但是对于我测试中的短字符串,它实际上比 python 略快。此外,此脚本小写任何输入,您必须将其修改为大写。将这些函数放入脚本中(或剪切并粘贴到 shell 中)后,您可以执行以下操作
inc_string abz9z9
inc_string abz9z9
and get back.
回来。
aca0a0
aca0a0
chr() {
[ "" -lt 256 ] || return 1
printf "\$(printf '%03o' "")"
}
ord() {
LC_CTYPE=C printf '%d' "'"
}
inc_string ()
{
string="";
lcstring=$(echo $string | tr '[:upper:]' '[:lower:]');
for ((position=$((${#lcstring}-1));position>=0;position--));do
if [ "${lcstring:position:1}" = 'z' ]; then
if [ "$position" -eq "$((${#lcstring}-1))" ]; then
newstring="${lcstring:0:$(($position))}a";
lcstring="$newstring";
elif [ "$position" -eq "0" ]; then
newstring="a${lcstring:$((position+1))}";
echo $newstring;
break;
else
newstring="${lcstring:0:$(($position))}a${lcstring:$((position+1))}";
lcstring="$newstring";
fi
elif [ "${lcstring:position:1}" = '9' ]; then
if [ "$position" -eq "$((${#lcstring}-1))" ]; then
newstring="${lcstring:0:$(($position))}0";
lcstring="$newstring";
elif [ "$position" -eq "0" ]; then
newstring="0${lcstring:$((position+1))}";
echo $newstring;
break;
else
newstring="${lcstring:0:$(($position))}0${lcstring:$((position+1))}";
lcstring="$newstring";
fi
else
if [ "$position" -eq "$((${#lcstring}-1))" ]; then
newstring="${lcstring:0:$(($position))}$(chr $(($(ord ${lcstring:position})+1)))";
echo $newstring;
break;
elif [ "$position" -eq "0" ]; then
newstring="$(chr $(($(ord ${lcstring:position})+1)))${lcstring:$((position+1))}";
echo $newstring;
break;
else
newstring="${lcstring:0:$(($position))}$(chr $(($(ord ${lcstring:position})+1)))${lcstring:$(($position+1))}";
echo $newstring;
break;
fi
fi
done
}

