0

I want to print two iterators named i and j of nested for loops whenever they are not equal. The error message:

syntax error near unexpected token `then'

#!/bin/bash
read n
array=()
for i in `seq 1 $n`
do
    read num
    array+=$num
done

count=0
count2=0
countmax=0
for i in `seq 1 $n`; do
    for j in `seq 1 $n`; do
        if [ $i -ne $j ]; then
            echo $i $j
        fi
    done
done

What have I done wrong?

  • 1
    works for me, though of course n should be set, $(...) is nicer than backticks and it might be prudent to quote the variables. – ilkkachu Dec 20 '17 at 22:11
  • 2
    One potential reason for that error would be a non-breaking space or such instead of normal space after the if. That would make it a different word, not recognized as the if keyword. And then then would be misplaced. (it would be if_[, with _ representing the nbsp) – ilkkachu Dec 20 '17 at 22:14
  • Does it work if you copy the code from this page and run it? – Hauke Laging Dec 20 '17 at 22:21
  • array+=$num probably doesn't do what you want, you may want array+=($num) instead – ilkkachu Dec 20 '17 at 23:16
1

What have I done wrong?

In no particular order,

  • You didn't have #!/bin/bash or equivalent as the first line.
  • You don't seem to have posted the actual script that's failing. (What you have here is syntactically correct.)
  • You haven't double-quoted your variables, "$n" instead of $n.
  • You're using obsolete backticks for evaluation instead of $( ...).
  • You haven't tested your code in https://shellcheck.net/
  • You haven't indented your code blocks to make them easier to read.
  • If you are adding elements to an array, use array+=($num). What you have in your code is string concatenation to the last element.
  • In the (new) first block you assign to elements (0 .. n-1) but you later use elements (1 .. n).
  • In the (new) second block you are comparing the indices for inequality rather than the array elements. Did you mean to compare "${array[$i]}" -ne "${array[$j]}" (or, for the (( ... )) construct, array[i] != array[j])?

(I should probably point out that some of these are good practice rather then essential coding rules.)

Here is your code with my suggestions applied:

#!/bin/bash
read -p 'Number of elements: ' n

array=(0)    # We don't use element zero
for i in $(seq "$n")
do
    read -p 'Element: ' num
    array+=($num)
done

for i in $(seq "$n")
do
    for j in $(seq "$n")
    do
        # Compare the array elements rather than the indices
        # Is this what you intended?
        if (( array[i] != array[j] ))
        then
            echo "${array[$i]} ${array[$j]}"
        fi
    done
done
  • Maybe slightly better (because easier to read): if (( array[i] != array[j] )) – user1934428 Dec 21 '17 at 8:54
  • @user1934428 ah yes. Good call. I'd switched from [ ... ] to [[ ... ]] and forgot that variables can be handled even better with (( ... )). – roaima Dec 21 '17 at 9:24
  • @roaima Backticks are not obsolete (or even deprecated) At best, their usage is not recommended. – fpmurphy Dec 21 '17 at 9:56
  • @fpmurphy1 I have to disagree with you on that point. See unix.stackexchange.com/q/126927/100397 and mywiki.wooledge.org/BashFAQ/082 and the POSIX statement about $(...) being preferred at pubs.opengroup.org/onlinepubs/9699919799/xrat/… – roaima Dec 21 '17 at 14:55
  • @roaima. Good to see that you went to the ONLY authoritative source on the issue, i.e. POSIX. Please explain how the term you used, i..e "obsolete" is equivalent to the term POSIX uses, i.e. "preferred". BTW, neither of the other two sources you quote are authoritative. – fpmurphy Dec 22 '17 at 0:52
0

I would also eliminate the use of seq by using for loops:

#!/bin/bash

read -p 'Number of elements: ' n

array=(0)
for (( i = 1; i <= n; i++ ))
do
    read -p 'Element: ' num
    array+=("$num")
done

for (( i = 1; i <= n; i++ ))
do
    for (( j = 1; j <= n; j++ ))
    do
        (( array[i] != array[j] )) && echo "${array[i]} ${array[j]}"
    done
done

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.