Incrementing ascii values

Hi All,

I require some help with the below:

I am trying to incriment the ascii value of a letter and then print it.

So basically "a" becomes "b" and "z" becomes "A".

Does anyone have any pointers?

Cheers,

Parks

Like this?

echo This is Something z write home aboutZ | tr 'a-zA-Z' 'b-zA-Za'
Uijt jt Tpnfuijoh A xsjuf ipnf bcpvua

Andrew

#include <stdio.h>

int main(int argc, char **argv ) {
  if ( *argv[1] == 'z' ) *argv[1]=64;
  printf( "%c\n", *argv[1]+1 );
  return 0;
}
$ cc -o mytest mypoorc.c

$ ./mytest a
b

$ ./mytest o
p

$ ./mytest z
A
1 Like
$
$
$ echo "abcdefghijklmnopqrstuvwxyz" | perl -plne 'tr/a-yz/b-zA/'
bcdefghijklmnopqrstuvwxyzA
$
$

tyler_durden

Depending on the locale settings, this may or may not do what you expect. For example, in an en_US.UTF-8 locale, a-z expands to aBbCc...YyZz. a-z and A-Z are almost identical in such a locale; a-z covers all letters except for "A", and A-Z covers all letters except for "z".

It's a good idea to explicitly set the applicable locale environment variables in the script when using range expressions.

Regards,
Alister

P.S. While helping to troubleshoot a script a while back, this particular "feature" claimed an hour of my life. NEVER AGAIN! :wink:

Sorry all I should have been more specific,

The aim is to be able to shift the letters via an inputed variable not just one possition.

Unfortunatly c is out of the question so ksh is the form that i require the code to be in.

Thanks for you assistance,

echo 'a' | nawk -f parks.awk 
echo 'a' | nawk -v shift=4 -f parks.awk 

parks.awk:

function initascii2dec()
{
  for(i=0;i<=255;i++) {
    ch=sprintf("%c", i)
    ascii2dec[ch] = i
  }
}
BEGIN {
  initascii2dec()
  if (!shift) shift=1
}
{
  printf("%c\n", ascii2dec[$1]+shift)
}
1 Like

Thanks vgersh99 thats what I was after!

shell, without external commands:

asciinext()
{
  printf "\\$(printf "%03o" $(( $(printf "%d" \'$1 ) + 1 )) )\n" 
}
$ asciinext a
b
1 Like
 $ echo "a" | ruby -e 'puts gets.succ' 
b  

Here is a solution in pure ksh that wraps properly, Scrutinizer was on the right track and I think if his solution worked (eg Z -> a and z -> a dont work), it would have been better than this.

#!/bin/ksh
A=( 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
    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 )
INC=$1
CNT=${#A[@]}
SU=$(printf "%d" \'A)
EU=$(printf "%d" \'Z)
SL=$(printf "%d" \'a)
EL=$(printf "%d" \'z)
shift
echo $@ | while read -n 1 L
do
   i=0
   p=$(printf "%d" \'$L)
   n=99
   [ $p -ge $SU -a $p -le $EU ] && n=$(( (p-SU+INC)%CNT))
   [ $p -ge $SL -a $p -le $EL ] && n=$(( (26+p-SL+INC)%CNT))
   [ $n -eq 99 ] && printf "$L" || printf "%s" ${A[n]}
done
echo
$ ./shift.ksh 1 Zhis is z test
aijt jt A uftu
 
$ ./shift.ksh 26 Zhis is z test
zHIS IS Z TEST
 
$ ./shift.ksh -2 $(./shift.ksh 2 This is a test)
This is a test