2013-05-29 3 views
6

У меня есть набор допустимых символов [0-9a-z_] и переменная, которой присваивается один из этих символов. То, что я хочу сделать, - это увеличить эту переменную до следующей в наборе.bash - переменные приращения, содержащие буквы

Если нужно, я могу обрабатывать «особые» случаи, когда он увеличивался бы от «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' 
+0

вы ищете это? http://stackoverflow.com/a/13128083/297323 –

ответ

6
y=b 
echo "$y" # this shows 'b' 
y=$(echo "$y" | tr "0-9a-z" "1-9a-z_") 
echo "$y" # this shows 'c' 

Обратите внимание, что это не обрабатывает случай, когда $ y = "_" (не уверен, что вы хотите, и в любом случае, вероятно, потребуется отдельная обработка), и если $ y длиннее одного символа, это будет «прирастить» все из них (т. е. «10» -> «21», «09g» -> «1ah» и т. Д.).

+0

Это то, что я искал. Я могу обрабатывать особые случаи, когда $ y больше одного символа или когда он равен «_». Это гораздо более приятное решение, чем уродливый массив, который я использовал. Благодаря! –

+0

'y = b; y = $ (tr "0-9a0-z" "1-9a-z_" <<< $ y); echo $ y; ' – dylnmc

3

Может быть, это может быть решение:

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]} 

Выход:

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 
+1

Это работает, и на самом деле довольно близко к тому, что я построил самостоятельно, но это не самое элегантное решение. Там должен быть лучший способ ... –

+0

Фактически это использует то же самое в идее, что вы приняли, но это использует меньше ресурсов. По крайней мере, две вилки меньше и не исполняются в других внешних программах. – TrueY

1

Вы можете начать с этого:

echo 0x$(($(printf "%x" "'b'") + 1)) | xxd -r 
-1

Я написал это для проекта, он использует функции chr и ord fucntions (также найденные здесь где-то) и некоторые чистые bash (только внешние вызовы в функции tr), если вы делаете более 100 символов, я бы использовал что-то другое, но для коротких строк в моем тестировании это на самом деле немного быстрее, чем python. Кроме того, этот сценарий содержит нижний регистр любого ввода, вам придется изменить его для верхнего регистра. после ввода этих функций в скрипте (или вырезать и вставить в оболочку), вы можете просто сделать

inc_string abz9z9

и получить обратно.

aca0a0

chr() { 
    [ "$1" -lt 256 ] || return 1 
    printf "\\$(printf '%03o' "$1")" 
} 

ord() { 
    LC_CTYPE=C printf '%d' "'$1" 
} 

inc_string() 
{ 
string="$1"; 
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 

} 
Смежные вопросы