Hyunil Kang
Hyunil Kang

Reputation: 41

How can I swap uppercase and lowercase alternatively?

I'm writing a program that can convert uppercase into lowercase and lowercase into uppercase alternatively. Here are some examples.

abcde -> aBcDe

ABCDE -> aBcDe

abCdE -> aBcDe

I know how to make it in c but not shell script. Here's the c code.

  1 #include <stdio.h>
  2 #include <ctype.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 
  6 int main(int args, char* argv[])
  7 {
  8 
  9     if(args != 2)
 10         exit(1);
 11     char buf[100];
 12     for(int i = 0; i < strlen(argv[1]); i++)
 13     {
 14         if(i%2 == 0)
 15             buf[i] = tolower(argv[1][i]);
 16         else
 17             buf[i] = toupper(argv[1][i]);
 18     }
 19     printf("%s\n", buf);
 20 }

Can you guys help me how to write it in shell script? Thank you.

Upvotes: 1

Views: 623

Answers (2)

Walter A
Walter A

Reputation: 19982

With sed you can repeatedly parse 2 chars, changing the first in lowercase and the second in uppercase. That seems nice, but how about the last character with a string with an odd number of chars?
First change the last char to lowercase. That is OK for an odd length string, and will be modified with the second command for an even length string:

if [ $# -ne 1 ]; then
   exit 1
fi
lastcharlow=$(sed -r "s/(.)$/\l\1/" <<< "${1}")
sed -r "s/(.)(.)/\l\1\u\2/g" <<<"${lastcharlow}"

The last 2 lines can be combined:

sed -r "s/(.)$/\l\1/; s/(.)(.)/\l\1\u\2/g" <<<"${1}"

EDIT: Text beneath

The sed solution is nice and short, but doesn't show how to loop through a string. When you really don't know a tool working for you, you can loop through your string. I will show 3 methods for changing the case of a char and two functions for looping through a string.

function upper {
   # tr '[:lower:]'  '[:upper:]' <<< $1
   # echo "${1^^}"                     
   typeset -u up; up="$1"; echo "${up}" 
}                                       

function lower {
   # tr '[:upper:]'  '[:lower:]' <<< $1
   # echo "${1,,}"                     
   typeset -l low; low="$1"; echo "${low}" 
}                                          

function grepsolution {
   i=0
   while read -r onechar; do
      (( i++ ))
      if [[ $((i%2)) = 0 ]] ; then
          printf "%s" $(upper "${onechar}" )
      else
          printf "%s" $(lower "${onechar}" )
      fi
   done < <(echo $1 | grep -o .)
   printf "\n"
}

function substr_solution {
   i=0
   while [ $i -lt ${#1} ]; do
      (( i++ ))
      if [[ $((i%2)) = 0 ]] ; then
          printf "%s" $(upper "${1:i-1:1}" )
      else
          printf "%s" $(lower "${1:i-1:1}" )
      fi
   done
   printf "\n"
}

for teststring in abcde abcdef ABCDE ABCDEF; do
   echo "Converting ${teststring}"
   printf "%-20s: " "grepsolution"
   grepsolution "${teststring}"
   printf "%-20s: " "substr_solution"
   substr_solution "${teststring}"
done

Upvotes: 2

user1934428
user1934428

Reputation: 22225

You didn't say what shell you want to use. Depending on the shell, this can be complicated or easy.

For example, in Zsh, it is very easy:

myvar="abcd"
myvar_uppercase=${(U)myvar}

Upvotes: -1

Related Questions