I want to use for loop with an array. I using the following command for this:

#! /bin/bash
rm -f /orch/list

arrayVM=($(cat /orch/servers | grep $1 | awk '{print $1}'))
for i in $arrayVM
        echo ${arrayVM[$i]}>>list

But when I check the list file I see only the first element of arrayVM array. What's wrong with my command?


The principle error is that for i in $arrayVM sets i to the first element in arrayVM, since there is no index. I am surprised that this does not give an error on the echo command, unless the first array element is numeric.

What you need is the iterative form of for:-

for (( i=0; i<${#arrayVM[*]}; ++i ))
    echo ${arrayVM[$i]}>>list

However, this is unnecessarily long-winded: much simpler is:-

for e in "${arrayVM[@]}"
    echo $e>>list

This assigns e to each element in turn, without enumerating them.

In the light of Fedorqui's answer, if arrayVM is not needed elsewhere, then there is a much simpler way to create the list file:-

cat /orch/servers | grep $1 | awk '{print $1}' >/orch/list

Or, since the cat is unnecessary:-

grep $1 </orch/servers | awk '{print $1}' >/orch/list
  • Thanks. I removed parentheses of define row. arrayVM=$(cat ......) and it works. – Arda Güven Aug 9 '17 at 15:22
  • 1
    Removing the parentheses makes arrayVM a long string with embedded new-lines if it is previously undeclared; if it is already declared as an array, then it will become a single-element array, and the element will be the long string. Run declare -p arrayVM after the assignment in each case to verify this. – AFH Aug 9 '17 at 15:41
  • I should have added that making arrayVM a long string will work, but not in the way you might expect. – AFH Aug 11 '17 at 11:20
  • My edit crossed with the questioner's comment on @fedorqui's answer, making my assumption invalid, but I shall leave it in place for the benefit of others. – AFH Aug 11 '17 at 11:33

If you don't need the data to be stored in an array but you also want to use every record for other things, you can loop normally through the data with a process substitution:

while IFS= read -r value _;
        echo "$value" >> list
done < <(grep "$1" /orch/servers)

With read -r value _ we are storing the first field in $value and the rest in the throw away variable $_.

  • I assumed in my answer that the array would be needed elsewhere. Otherwise, cat /orch/servers | grep $1 | awk '{print $1}'>/orch/list would suffice. – AFH Aug 11 '17 at 11:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.