For some reason when using “read -a” my script is only taking the first element of the line into the array. For example, when inputting a string such as “canada China”, the output of the program simply reads:
canada c Canada changed to uppercase.
Instead of:
canada China c Canada Changed to uppercase. C China Already uppercase.
The instructions for my assignment are as follows:
Create a script that reads the user’s input and stores it in an Array. Then, loop over the Array and :
- If the first character is lowercase, change it to be uppercase and write next to it “Changed to uppercase”.
- If the first letter is already uppercase, output the input word then write next to it “Already uppercase”.
- If the first character is not a letter, output the input word then write next to it “Doesn’t Start with a letter”. Use an Associative Array to do the conversion from lowercase to uppercase [converterArray=([a]=A [b]=B …)]
And here is my code:
#!/bin/bash declare -A converterArray converterArray=([a]=A [b]=B [c]=C [d]=D [e]=E [f]=F [g]=G [h]=H [i]=I [j]=J [k]=K [l]=L [m]=M [n]=N [o]=O [p]=P [q]=Q [r]=R [s]=S [t]=T [u]=U [v]=V [w]=W [x]=X [y]=Y [z]=Z) read -p "Enter elements separated by space, return to end: " -a inputArray lowercasemsg=" Changed to uppercase." uppercasemsg=" Already uppercase." notlettermsg=" Doesn't start with a letter." echo $inputArray for word in $inputArray; do firstchar=${word:0:1} echo $firstchar case $firstchar in [a-z]*) word = ${converterArray[$firstchar]}${word:1} echo $word$lowercasemsg ;; [A-Z]*) echo $word$uppercasemsg ;; *) echo $word$notlettermsg ;; esac done
EDIT: Thanks to John’s help the problem has been solved. I also fixed an issue with checking the case of the letter ([a-z] vs. [[:lower:]]), and removed the unnecessary “echos” for debugging.
#!/bin/bash declare -A converterArray converterArray=([a]=A [b]=B [c]=C [d]=D [e]=E [f]=F [g]=G [h]=H [i]=I [j]=J [k]=K [l]=L [m]=M [n]=N [o]=O [p]=P [q]=Q [r]=R [s]=S [t]=T [u]=U [v]=V [w]=W [x]=X [y]=Y [z]=Z) read -p "Enter elements separated by space, return to end: " -a inputArray lowercasemsg=" Changed to uppercase." uppercasemsg=" Already uppercase." notlettermsg=" Doesn't start with a letter." for word in "${inputArray[@]}"; do firstchar=${word:0:1} case $firstchar in [[:lower:]]*) inputString=${converterArray[$firstchar]}${word:1} echo $word$lowercasemsg ;; [[:upper:]]*) echo $word$uppercasemsg ;; *) echo $word$notlettermsg ;; esac done
(2nd edit: Fixed line where I forgot to put spaces around equals sign, originally forgotten in previous edit)
Advertisement
Answer
If $array
is an array, "${array[@]}"
gives all of the array elements. A bare $array
references only the first element.
echo "${inputArray[@]}" for word in "${inputArray[@]}"; do ... done