Yousef Hadder
Yousef Hadder

Reputation: 63

Bash script string processing

I wrote a script that reads a Plain text and a key, and then loops trough each character of plain text and shifts it with the value of the corresponding character in key text, with a=0 b=1 c=2 ... z = 25

the code works fine but with a string of size 1K characters it takes almost 3s to execute.

this is the code:

    small="abcdefghijklmnopqrstuvwxyz" ## used to search and return the position of some small letter in a string
    capital="ABCDEFGHIJKLMNOPQRSTUVWXYZ" ## used to search and return the position of some capital letter in a string

    read Plain_text
    read Key_text
    ## saving the length of each string
    length_1=${#Plain_text}
    length_2=${#Key_text}
    printf " Your Plain text is: %s\n The Key is: %s\n The resulting Cipher text is: " "$Plain_text" "$Key_text"

        for(( i=0,j=0;i<$length_1;++i,j=`expr $(($j + 1)) % $length_2` )) ## variable 'i' is the index for the first string, 'j' is the index of the second string
        do
            ## return a substring statring from position 'i' and with length 1
            c=${Plain_text:$i:1}
            d=${Key_text:$j:1}  

            ## function index takes two parameters, the string to seach in and a substring,
            ## and return the index of the first occerunce of the substring with base-insex 1

            x=`expr index "$small" $c` 
            y=`expr index "$small" $d`

            ##shifting the current letter to the right with the vaule of the corresponding letter in the key mod 26
            z=`expr $(($x + $y - 2)) % 26`

            ##print the resulting letter from capital letter string
            printf "%s" "${capital:$z:1}"
        done
    echo ""

How is it possible to improve the performance of this code. Thank you.

Upvotes: 0

Views: 279

Answers (3)

Walter A
Walter A

Reputation: 20002

You will have a lot of repeating chars in a 1K string.
Imagine the input was 1M.

You should calculate all request/respond pairs in front, so your routine only has to lookup the replacement.
I would think of a solution with arrays is the best approach here.

Upvotes: 0

Soheil
Soheil

Reputation: 837

you can change character like this

a=( soheil )
echo ${a/${a:0:1}/${a:1:1}} 

for change all char use loop like for and for change char to upper

echo soheil | tr "[:lower:]" "[:upper:]"

i hope i understand your question. be at peace

Upvotes: 0

Michael Jaros
Michael Jaros

Reputation: 4681

You are creating 4 new processes in each iteration of your for loop by using command substitution (3 substitutions in the body, 1 in the head). You should use arithmetic expansion instead of calling expr (search for $(( in the bash(1) manpage). Note that you don't need the $ to substitute variables inside $(( and )).

Upvotes: 1

Related Questions