0

I have an array of domains that I am attempting to iterate through and check if a string from a file matches any of the domains in the array. However, when the for loop starts, I get an error

line 64: www.google.com: syntax error: invalid arithmetic operator (error token is ".google.com")

the array and for loop look like this:

sites=("www.google.com" "www.bing.com" "www.yahoo.com" "www.duckduckgo.com")

while read line; do
    csvString=($echo "$line");
    greppedDomain=$(echo "$line" | grep -Eo '[A-Za-z0-9]{2,62}\.[A-Za-z0-9]{2,62}\.[A-Za-z]{2,62}'); 
    for i in "${sites[@]}"; do
        if [ "$greppedDomain" = "${sites[$i]}" ]
        then
            sitesOut+=($csvString);
        fi
    done
done < sitelist.txt

I am currently at a loss, maybe it is an issue with the way the grep output stores in the variable?

  • 1
    As mentioned in a now-deleted answer, csvString=($echo "$line") is wrong. You have no variable called echo. You just want csvString=$line since you're not using the csvString variable as an array. But you might as well use read csvString directly. – glenn jackman Jun 13 at 17:58
  • 1
    There are a few other issues. Paste your code into shellcheck.net for tips – glenn jackman Jun 13 at 17:58
2

You are using a string element of the array as the numeric index:

for i in "${sites[@]}"; do
    if [ "$greppedDomain" = "${sites[$i]}" ]

In a numerically indexed array, when dereferencing, the index part in square brackets is actually an arithmetic expression. That allows you to do index arithmetic like x[i]=${x[i+1]} for example.

To reproduce the error:

$ x=(a b c)
$ i="www.google.com"
$ echo "${x[i]}"
bash: www.google.com: syntax error: invalid arithmetic operator (error token is ".google.com")

To demonstrate the arithmetic nature of the array index, let's look at the string in an arithmetic expression:

$ echo $((www.google.com))
bash: www.google.com: syntax error: invalid arithmetic operator (error token is ".google.com")

Same error.

The error token is ".google.com" -- why is that?

  1. when parsing $((www.google.com)) the www part will be taken as a shell variable.

    • In an arithmetic expression, variables do not need to be prefixed with a dollar sign
    • test: a=5; b=7; echo $(( a * b ))
  2. but, arithmetically, there is no . operator, so the parser does not know what to do with the rest of the expression.

0

There are two standardish ways to iterate over an array in bash. One option is to loop over the element values directly. This will run the loop with elem set to "www.google.com", then with "www.bing.com", etc:

sites=("www.google.com" "www.bing.com" "www.yahoo.com" "www.duckduckgo.com")
for elem in "${sites[@]}"; do
    echo "The element is: $elem"
done

The other option is to loop over the array indexes, that is, 0, 1, 2, etc (where ${sites[0]} is "www.google.com", ${sites[1]} is "www.bing.com", etc):

for i in "${!sites[@]}"; do    # The ! makes it list indexes, rather than elements
    echo "The $i'th element is: ${sites[i]}"
done

The problem here is that you've mixed these methods, looping over the element values, but then treating them as indexes.

Some other problems:

csvString=($echo "$line");

In the first place, the ($ should be $(, and in the second place you shouldn't use $(echo ...) -- the echo and the $( ) mostly cancel each other out (except for some possible parsing oddities you probably don't want). Just use this:

csvString=$line

BTW, notice that I didn't put a semicolon at the end? In the shell, you don't need semicolons at the ends of lines in shell (except some odd cases like the double-semicolon that ends case options). You only need them if you're putting multiple command-like things on the same line. For instance, this:

if somethingorother; then
    echo "this"; echo "that"
fi

Could be equivalently written:

if somethingorother
then
    echo "this"
    echo "that"
fi

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.