-2

I have tried several different search terms but have not found exactly what I want, I am sure there is already an answer for this so please point me to it if so.

I would like to understand how to increment a letter code given a standard number convention in a bash script.

Starting with AAAA=0 or with leading zerosAAAA=000000 (26x26x26x26) I would like to increment the value with a a positive single digit each time, so aaab=000001,aaac=000002 and aaba=000026 and aaaca=000052 etc.

Thanks Art!

art vanderlay
  • 2,341
  • 4
  • 35
  • 64
  • You might find this useful: http://stackoverflow.com/questions/890262/integer-ascii-value-to-character-in-bash-using-printf converting a character to a number and back again. The rest is just math. – JNevill Oct 16 '15 at 18:59
  • @JNevill no that seems to be a key code. I am after a value that is a UUID for an increasing sequence of numbers. – art vanderlay Oct 16 '15 at 20:21
  • If you need to convert a number (an UUID) to a string of letters, please look at the conversion function in my answer. –  Oct 16 '15 at 23:24

3 Answers3

4

I guess this is what you want

echo {a..z}{a..z}{a..z}{a..z} | tr ' ' '\n' | nl

will be too long, perhaps test with this first

 echo {a..z}{a..z} | tr ' ' '\n' | nl

if you don't need the line numbers remove last pipe and nl

If you need the output in xxxx=nnnnnn format, you can use awk

echo {a..z}{a..z}{a..z}{a..z} | tr ' ' '\n' | awk '{printf "%s=%06d\n", $0, NR-1}'

aaaa=000000
aaab=000001
aaac=000002
aaad=000003
aaae=000004
aaaf=000005
aaag=000006
aaah=000007
aaai=000008
aaaj=000009
...
zzzv=456971
zzzw=456972
zzzx=456973
zzzy=456974
zzzz=456975
karakfa
  • 66,216
  • 7
  • 41
  • 56
1

Fast

If you are aiming for speed and simplicity:

#!/bin/bash
i=0
for text in {a..z}{a..z}{a..z}{a..z}; do
    printf '%06d %5.5s\n' "$i" "$text"
    (( i++ ))
done

Precise

Aiming at having a function that convert any number to the character string:

We must Understand that what you are describing is a number written in base 26, using the character a as 0, b as 1, c as 3, etc.

Thus, aaaa means 0000, aaab means 0001, aaac means 0002, .... aaaz means 0025
and aaba means 0026, aaca means 0052.

bc could do the base conversion directly (as numbers):

$ echo 'obase=26; 199'|bc
07 17

The 7th letter is: a0, b1, c2, d3, e4, f5, g6, (h)7,
the 17th letter is (r).

If we set the variable list to: list=$(printf '%s' {a..z}) or list=abcdefghijklmnopqrstuvwxyz

We could get each letter from the number with: ${list:7:1} and ${list:17:1}

$ echo "${list:7:1} and ${list:17:1}"
h and r
$ printf '%s' "${list:7:1}" "${list:17:1}"    # Using printf:
hr

Script

All together inside an script, is:

#!/bin/bash

list=$(printf '%s' {a..z})

getletters(){
    local numbers
    numbers="$(echo "obase=26; $1"|bc)"
    for number in $numbers; do
        printf '%s' "${list:10#$number:1}";
    done;
    echo;
}

count=2
limit=$(( 26**$count - 1 ))

for (( i=0; i<=$limit; i++)); do
    printf '%06d %-5.5s\n' "$i" "$(getletters "$i")"
done

Please change count from 2 to 4 to get the whole list. Be aware that such list is more than half a million lines: The limit is 456,975 and will take some time.

0

With perl, you can ++ a string to increment the letter:

for (my ($n,$s) = (0,"aaaa"); $n < 200; $n++, $s++) {
    printf "%s=%0*d\n", $s, length($s), $n;
}

outputs

aaaa=0000
aaab=0001
aaac=0002
aaad=0003
...
aaby=0050
aabz=0051
aaca=0052
aacb=0053
...
aahp=0197
aahq=0198
aahr=0199
glenn jackman
  • 238,783
  • 38
  • 220
  • 352