【问题标题】:Decrement variables that contain letters递减包含字母的变量
【发布时间】: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'

【问题讨论】:

    标签: linux bash ubuntu sed


    【解决方案1】:

    优势

    test=$(tr 1-9a-zA-Z 0-9a-zA-Y <<<"$test")
    

    它是否正确(我认为)将a 减少到9A 减少到z。如果这不是您想要的顺序,也很容易调整。

    详情请参阅 man tr。这是tr的Gnu版本; Posix 不保证字符范围,但大多数tr 实现都有它们。 &lt;&lt;&lt;“这里的字符串”也是常用的扩展,bash 实现的。

    【讨论】:

    • 这会将ba翻译成a9
    • @sundeep,是的,它将保持 $ 不变。 OP 说他有一个“包含这些字符中的 一个”的变量,所以我想我已经回答了被问到的问题。 (我对字符串 ase 有类似的答案,所以请随时提出不同的问题。
    【解决方案2】:
    test=$(printf "\\$(printf '%03o' "$(($(printf '%d' "'$test") - 1 ))")")
    

    【讨论】:

    【解决方案3】:

    你可以试试这个:

    #!/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
    

    参考:
    http://mywiki.wooledge.org/BashFAQ/071

    【讨论】:

    • 不,这会将A 的ascii 值(例如)减少为@ 的ascii 值,它不在提供的列表中:0-9a-zA-Z
    【解决方案4】:

    如果我们为整个字符串设置一个变量(比如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)。

    它可能会扩展到几个字符,但这不是被要求的。

    【讨论】:

      猜你喜欢
      • 2013-05-25
      • 2018-04-23
      • 1970-01-01
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多