0

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

6
  • 2
    If you're using bash then this script can be simplified a lot Commented Nov 3, 2017 at 21:27
  • 1
    Pretty sure it's Bash, considering the existence of arrays in there, no? Commented Nov 3, 2017 at 21:28
  • @anubhava, yup I'm using bash shell. Initial script was very manual without any loop This is my first attempt to simplify it. Commented Nov 3, 2017 at 21:29
  • 1
    Why not just printf "%d\n" "'A'"? (or any other character to get the ASCII value) or you can use LC_CTYPE=C printf "%d\n" "'A'". Commented Nov 3, 2017 at 21:37
  • 1
    array index is from 0 to length-1; Commented Nov 3, 2017 at 21:42

3 Answers 3

3

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 
Sign up to request clarification or add additional context in comments.

2 Comments

for i; seems to lack any values to set i to.
That's not correct. for i; is equivalent of for i in "$@";
1

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

Comments

1

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"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.