4

I am having some trouble figuring out how to iterate over space separated words/characters in a shell script. For instance I would like to iterate over a variable containing the characters in the alphabet separated by a space.

NOTE: The result should be the same even if the alphabet variable contained space separated strings instead of characters, i.e "aa bb cc ..." instead of "a b c .."

I have tried a lot of the alternatives provided from: How to split a line into words separated by one or more spaces in bash?

Example:

  local alphabet="a b c d e f g h i j k l m n o p q r s t u v w x y z"
  local index="0"
  for character in $alphabet; do
      index=$((++index))                                      
      echo "$index. $character"
      # Possibility to do some more stuff
  done 

Expected/Desired output:

1. a
2. b
3. c
and so on..

Result:

1. a b c d e f g h i j k l m n o p q r s t u v w x y z

Additional tests(without success):

  ####################################################################
  local alphabet="a b c d e f g h i j k l m n o p q r s t u v w x y z"
  local index="0"
  for character in ${alphabet[@]}; do
      index=$((++index))                                      
      echo "$index. $character"
      # Possibility to do some more stuff
  done 

  ####################################################################
  local alphabet="a b c d e f g h i j k l m n o p q r s t u v w x y z"                                            
  local alphabetArray=( ${alphabet} )                                                                             
  local index="0"                                                                                                 
  for character in "${alphabetArray[@]}"; do                                                                      
      index=$((++index))                                                                                          
      echo "$index. $character"                                                                                   
      # Possibility to do some more stuff                                                                                        
  done 

  ####################################################################
  local alphabet="a b c d e f g h i j k l m n o p q r s t u v w x y z"                                            
  local alphabetArray=( ${alphabet} )                                                                             
  local index="0"                                                                                                 
  for character in ${alphabetArray}; do                                                                           
      index=$((++index))                                                                                          
      echo "$index. $character"                                                                                   
      # Possibility to do some more stuff                                                                                        
  done

Could someone provide a solution on how to solve this(I would prefer a solution that iterates the alphabet variable without explicitly using an index variable, i.e $alphabet[index] )?

pynexj
  • 19,215
  • 5
  • 38
  • 56
Henrik
  • 405
  • 1
  • 8
  • 19
  • 3
    Your code should work. The only reason it wouldn't is if you've set the variable `IFS` to something other than the default whitespace characters. – Barmar Sep 05 '17 at 13:47
  • 3
    I can't reproduce the problem. Check your script for `IFS` assignments. – Barmar Sep 05 '17 at 13:50
  • 2
    Me neither; works as expected. – mouviciel Sep 05 '17 at 13:54
  • It's working as expected. Can't reproduce the problem. – Chamin Wickramarathna Sep 05 '17 at 13:56
  • @Barmar you'r correct i should help him with his code instead of providing links. The default value for IFS consists of whitespace characters (to be precise: space, tab and newline) you code should work unless like Barmar said your IFS is not space, tab or newline try printing the value of your IFS echo "$IFS" – Seifeddine Besbes Sep 05 '17 at 14:00
  • Thanks for your feedback, it was a f**kup from my side. see my post below. – Henrik Sep 05 '17 at 14:33

2 Answers2

7

Thanks for your help. I discovered the error thanks to your feedback.

I thought that it was irrelevant when I posted this question but I was experimenting with functions in my .zshrc file. Hence I was using (just my assumption) the zsh interpreter and not the sh or bash interpreter.

By realizing that this could be a potential problem, I googled and found the following How to iterate through string one word at a time in zsh

So I tested the following and it works as expected:

  setopt shwordsplit                                                                                              
  local alphabet="a b c d e f g h i j k l m n o p q r s t u v w x y z"                                            
  local index="0"                                                                                                 
  for character in $alphabet; do                                                                                  
      index=$(($index+1))                                                                                         
      echo "$index. $character"                                                                                   
      # Possibility to do some more stuff                                                                                        
  done                                                                                                            
  unsetopt shwordsplit

NOTE:

index=$((++$index))
and/or
index=$(($index++))

Doesn't seem to work as I expected in zsh.

... The little gritty details, I should have used:

((++index)) 
or
((index++))
instead of
index=$((++$index))
Henrik
  • 405
  • 1
  • 8
  • 19
0

Try this

IFS=$' \t\n'
local alphabet="a b c d e f g h i j k l m n o p q r s t u v w x y z"
local index="0"
for character in $alphabet; do
  index=$((++index))                                      
  echo "$index. $character"
  # Possibility to do some more stuff
done

Hope it helps

  • Hi! Thanks for your suggestion, however I tested this without success for my particular issue. – Henrik Sep 05 '17 at 14:31