bash 语法错误:解析数组时算术运算符无效(错误标记为“.google.com”)

bash 语法错误:解析数组时算术运算符无效(错误标记为“.google.com”)

我有一个域数组,我试图迭代它并检查文件中的字符串是否与数组中的任何域匹配。但是,当 for 循环开始时,出现错误

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

数组和 for 循环如下所示:

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

我目前不知所措,也许这是 grep 输出存储在变量中的方式的问题?

答案1

您使用数组的字符串元素作为数字索引:

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

在数字索引数组中,当取消引用时,方括号中的索引部分实际上是一个算术表达式。这允许您进行索引算术,例如x[i]=${x[i+1]}

要重现该错误:

$ 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")

为了演示数组索引的算术性质,让我们看一下算术表达式中的字符串:

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

同样的错误。

错误标记是“.google.com”——这是为什么?

  1. 解析$((www.google.com))www部分时将被视为外壳变量

    • 在算术表达式中,变量不需要以美元符号作为前缀
    • 测试:a=5; b=7; echo $(( a * b ))
  2. 但是,从算术上讲,没有.运算符,因此解析器不知道如何处理表达式的其余部分。

答案2

在 bash 中迭代数组有两种标准方法。一种选择是直接循环元素值。这将运行设置为“www.google.com”的循环elem,然后设置为“www.bing.com”等:

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

另一种选择是循环数组索引,即 0、1、2 等(其中${sites[0]}是“www.google.com”,${sites[1]}是“www.bing.com”等):

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

这里的问题是您混合了这些方法,循环遍历元素值,然后将它们视为索引。

其他一些问题:

csvString=($echo "$line");

首先, 应该($$(,其次你不应该使用$(echo ...)- theecho和 the$( )大部分相互抵消(除了一些你可能不想要的可能的解析奇怪的情况)。只需使用这个:

csvString=$line

顺便说一句,注意到我没有在末尾加分号吗?在 shell 中,您不需要在 shell 的行末尾使用分号(除了一些奇怪的情况,例如结束case选项的双分号)。仅当您将多个类似命令的内容放在同一行时才需要它们。例如,这个:

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

可以等价地写成:

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

相关内容