changing position of character in string bash

i have this string

E="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

any idea how to change the position of the letters with its neighbour if the user enters no

and it will continue changing position until user satisfied with the string OR it has reach end of the string.

is the position of 1st correct? Y/N
N
E=BACDEFGHIJKLMNOPQRSTUVWXYZ
*some of my code here*
are u satisfied? Y/N
N

is the position of 2nd correct? Y/N
N
E=BCADEFGHIJKLMNOPQRSTUVWXYZ
*some of my code here*
are u satisfied? Y/N
N

is the position 3rd correct? Y?N
Y
E=BCADEFGHIJKLMNOPQRSTUVWXYZ
*some of my code here*
are u satisfied? Y/N
N

is the position 4th correct? Y?N
Y
E=BCADEFGHIJKLMNOPQRSTUVWXYZ
*some of my code here*
are u satisfied? Y/N
Y

*exit prog*

any help will greatly appreciated. thanks

edited i got this code from a forum. worked perfectly. but any idea how to swap next character after it have done once? for example ive done the first position, and i want to run it for the second character? any idea?

dual=ETAOINSHRDLCUMWFGYPBVKJXQZ
phrase='E'
rotat=1
newphrase=$(echo $phrase | tr "${dual:0:26}" "${dual:${rotat}:26}")
echo ${newphrase}

Upvotes: 1

Views: 669

Answers (3)

Tim Zimmermann
Tim Zimmermann

Reputation: 6420

You will have to use a loop.

#!/bin/bash

E="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
echo "$E"

for (( i = 1; i < ${#E}; i++ )); do
  echo "Is position $i correct? Y/N"
  read answer

  if [ "$answer" == "N" -o "$answer" == "n" ]
  then
    E="${E:0:$i-1}${E:$i:1}${E:$i-1:1}${E:$i+1}"
  fi

  echo "$E"
  echo "Are you satisfied? Y/N"
  read answer

  if [ "$answer" == "Y" -o "$answer" == "y" ]
  then
    break
  fi
done

The loop iterates over every character of the string. The string altering happens in the first if clause. It's nothing more than basic substring operations. ${E:n} returns the substring of E starting at position n. ${E:n:m} returns the next m characters of E starting at position n . The remaining lines are the handling if the user is satisfied and wants to exit.

Upvotes: 3

Jdamian
Jdamian

Reputation: 3115

From bash man pages:

   ${parameter:offset}
   ${parameter:offset:length}
          Substring Expansion.  Expands to up to length characters of parameter starting at  the  character  specified  by  offset.   If
          length is omitted, expands to the substring of parameter starting at the character specified by offset.  length and offset are
          arithmetic expressions (see ARITHMETIC EVALUATION below).  length must evaluate to a number greater than or equal to zero.  If
          offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter.  If param-
          eter is @, the result is length positional parameters beginning at offset.  If parameter is an array name indexed by @  or  *,
          the result is the length members of the array beginning with ${parameter[offset]}.  A negative offset is taken relative to one
          greater than the maximum index of the specified array.  Note that a negative offset must be separated from  the  colon  by  at
          least one space to avoid being confused with the :- expansion.  Substring indexing is zero-based unless the positional parame-
          ters are used, in which case the indexing starts at 1.

Examples:

pos=5
E="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
echo "${E:pos:1}  # print 6th character (F)
echo "${E:pos}    # print from 6th character (F) to the end

What dou you mean when you say "its neighbour"? Excepting first and last characters, every character in the string has two neighbours.

To exchange the "POS" character (starting from 1) and its next one (POS+1):

E="${E:0:POS-1}${E:POS:1}${E:POS-1:1}${E:POS+1}"

Upvotes: 0

Bentoy13
Bentoy13

Reputation: 4956

With bash, you can extract a substring easily:

${string:position:length}

This syntax allows you to use variable extensions, so it is quite straightforward to swap two consective characters in a string:

E="${dual:0:$rotat}${dual:$((rotat+1)):1}${dual:$rotat:1}${dual:$((rotat+2))}"

Arithmetics may need to be enclosed into $((...)).

Upvotes: 1

Related Questions