синтаксическая ошибка bash :недопустимый арифметический оператор (токен ошибки — «.google.com» )при синтаксическом анализе массива

Вы хотите вычислить сумму полей для каждой записи, так что просто:

awk '{sum = 0; for (i = 1; i <= NF; i++) sum += $i; print sum}' < file1 > file2

Фигурные скобки начинают оператор действия , который выполняется в каждой строке ввода; нет предшествующего условия , которое ограничивало бы его выполнение строками, удовлетворяющими такому условию .

В каждой строке:

  1. Инициализировать переменную sumнулем.
  2. Перебрать поля, начиная с поля #1 и заканчивая последним полем (специальной переменной NF), и увеличивать sumна значение этого поля($i).
  3. Печать значения переменной sum.
0
08.01.2020, 17:07
2 ответа

Вы используете строковый элемент массива в качестве числового индекса:

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
28.01.2020, 02:30

В bash есть два стандартных способа перебора массива. Одним из вариантов является прямой цикл по значениям элементов. Это запустит цикл с elem, установленным на «www.google.com», затем с «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...)--echoи $( )в большинстве случаев компенсируют друг друга (, за исключением некоторые возможные странности синтаксического анализа, которые вам, вероятно, не нужны ). Просто используйте это:

csvString=$line

Кстати, заметили, что я не поставил точку с запятой в конце? В оболочке вам не нужны точки с запятой на концах строк в оболочке (, за исключением некоторых странных случаев, таких как двойная -точка с запятой, которая заканчивается caseoptions ).Они нужны вам только в том случае, если вы помещаете несколько команд -в одну строку. Например, это:

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

Можно было бы написать эквивалентно:

if somethingorother
then
    echo "this"
    echo "that"
fi
0
28.01.2020, 02:30

Теги

Похожие вопросы