Charlotte Russell
Charlotte Russell

Reputation: 1475

Shell Script: Arithmetic operation in array

I'm doing for fun and this as part of my learning process in Shell scripting.

Let say I have initial input A B C

What I'm trying to do is to split the string and convert each of them to decimal value.

A B C = 65  66  67

Then I'll add the decimal value to random number, let say number 1.

Now, decimal value will become = 66 67 68

Finally, I'll convert the decimal to the original value again which will become B C D

ubuntu@Ubuntu:~$ cat testscript.sh -n
        #!/bin/bash
     1  string="ABC"
     2
     3  echo -e "\nSTRING = $string"
     4  echo LENGTH = ${#string}
     5
     6  # TUKAR STRING KE ARRAY ... word[x]
     7  for i in $(seq 0 ${#string})
     8      do word[$i]=${string:$i:1}
     9  done
    10
    11  echo -e "\nZero element of array is [ ${word[0]} ]"
    12  echo -e "Entire array is [ ${word[@]}] \n"
    13
    14  # CHAR to DECIMAL
    15  for i in $(seq 0 ${#string})
    16   do
    17          echo -n ${word[$i]}
    18          echo -n ${word[$i]} | od -An -tuC
    19          chardec[$i]=$(echo -n ${word[$i]} | od -An -tuC)
    20  done
    21
    22  echo -e "\nNEXT, DECIMAL VALUE PLUS ONE"
    23  for i in $(seq 0 ${#string})
    24   do
    25    echo `expr ${chardec[$i]} + 1`
    26  done
    27
    28  echo

This is the output

ubuntu@Ubuntu:~$ ./testscript.sh 

STRING = ABC
LENGTH = 3

Zero element of array is [ A ]
Entire array is [ A B C ] 

A  65
B  66
C  67

NEXT, DECIMAL VALUE PLUS ONE
66
67
68
1

As you can see in the output, there are 2 problems (or maybe more)

  1. The last for loop processing additional number. Any idea how to fix this?
NEXT, DECIMAL VALUE PLUS ONE
66
67
68
1
  1. This is the formula to convert decimal value to char. I'm trying to put the last value to another array and then put it in another loop for this purpose. However, I'm still have no idea how to do this in loop based on previous data.
ubuntu@Ubuntu:~$ printf "\x$(printf %x 65)\n"
A

Please advise

Upvotes: 0

Views: 564

Answers (3)

Alcamtar
Alcamtar

Reputation: 1582

seq is from FIRST to LAST, so if your string length is 3, then seq 0 3 will give you <0,1,2,3>. Your second to last loop (lines 16-20) is actually running four iterations, but the last iteration prints nothing.

To printf the ascii code, insert it inline, like

printf "\x$(printf %x `expr ${chardec[$i]} + 1`) "

or more readably:

dec=`expr ${chardec[$i]} + 1`
printf "\x$(printf %x $dec)\n"

Upvotes: 1

karakfa
karakfa

Reputation: 67467

awk to the rescue!

simpler to do the same in awk environment.

$ echo  "A B C" | 
  awk 'BEGIN{for(i=33;i<127;i++) o[sprintf("%c",i)]=i} 
            {for(i=1;i<=NF;i++) printf "%c%s", o[$i]+1, ((i==NF)?ORS:OFS)}'


B C D

Upvotes: 1

anubhava
anubhava

Reputation: 785058

Using bash you can replace all of your code with this code:

for i; do
   printf "\x"$(($(printf '%x' "'$i'") +1))" "
done
echo

When you run it as:

./testscript.sh P Q R S

It will print:

Q R S T 

Upvotes: 3

Related Questions