Как добавить номер, назначенный как массив

#linux #bash #shell

#linux #bash #оболочка

Вопрос:

У меня есть этот скрипт, который должен считывать данные из двух текстовых файлов и добавлять их. В этом отношении я использовал array.

Я могу прочитать данные, но есть проблема с добавлением.

 #!/bin/bash
n=1
declare -a data1
while read data1
do
data1[$n]=$data1
n=$(( n 1 ))
done <analysisSBM105.out
echo ${data1[1]}
echo ${data1[2]}
echo ${data1[3]}
echo ${data1[4]}

m=1
declare -a data2
while read data2
do
data2[$m]=$data2
m=$(( m 1 ))
done <analysisSBM105.out
echo ${data2[1]}
echo ${data2[2]}
echo ${data2[3]}
echo ${data2[4]}

i=1
declare -a dataAll
while [ $i -le 4 ];
do
${dataAll[$i]}= $( ${data1[$i]} ${data2[$i]} )


i=$(( i 1 ))

done

echo ${dataAll[1]}
echo ${dataAll[2]}
echo ${dataAll[3]}
echo ${dataAll[4]}
  

Вместо ${dataAll[$i]}= $( ${data1[$i]} ${data2[$i]} ) этого я также использовал 'expr ${data1[$i]} ${data2[$i]}'
Файл analysisSBM105.out содержит следующее

 6436
4167
1933
164
172

  

Но все равно это не работает. Ошибка

 6436
4167
1933
164
6436
4167
1933
164
Report105.sh: line 35: dataAll[1]: command not found
Report105.sh: line 35: dataAll[2]: command not found
Report105.sh: line 35: dataAll[3]: command not found
Report105.sh: line 35: dataAll[4]: command not found


  

Желаемый результат следующий.

 12872
8334
3866
328
344
  

Комментарии:

1. что происходит в ${dataAll[$i]}= $( ${data1[$i]} ${data2[$i]} ) ? Вы правильно сделали data2[$m]=$data2 — так что просто следуйте соглашению, нет?

2. @KamilCuk Я хочу суммировать их и сохранить в массиве dataAll[$ i] . И data2[$m]=$data2 сработало.

3. вместо ${dataAll[$i]}= $( ${data1[$i]} ${data2[$i]} ) … попробуйте dataAll[$i]=$(( ${data1[$i]} ${data2[$i]} ))

4. Результат @markp-fuso равен « Report105.sh : строка 35: dataAll[1]: команда не найдена «

5.Удалите пробел после и перед = . Это dataAll[$i]=$(( не dataAll[$i] =$((

Ответ №1:

Bash использует пространство. Присвоение переменной имеет = символ без пробелов ни перед, ни после него.

 ${dataAll[$i]}= $( ${data1[$i]} ${data2[$i]} )
                   ^^^^^^^^^^^^^^^^^^^^^^^^^   - command to run
                ^^                           ^ - command substitution, runs command inside
               ^                               - space after `=` - it's not assignment
^^^^^^^^^^^^^^^                                - runs a command named that after expansion
  

хотя, я думаю, вы хотели сделать:

 dataAll[i]=$(( data1[i]   data2[i] ))
               ^^^^^^^^^^^^^^^^^^^    - expression to calculate, `${..}` is not needed
           ^^^                     ^^ - arithemtic expansion   
          ^                           - no spaces around =
^^^^^^^^^^                            - variable name
  

Примечания:

  • declare -a array не требуется. Вы можете просто использовать dataAll[0]=something сразу.
  • тогда легче писать for ((i=0;i<4; i)) i=0;while [ "$i" -le 4 ]; do something; i=$((i 1)); done . Также вы можете for i in $(seq 4)
  • Сделайте правильный отступ в своем коде.
  • Используйте http://shellcheck .net для проверки вашего кода
  • array[<here>] Часть <here> выполняется как арифметическое выражение, это означает, что переменные автоматически расширяются. dataAll[$i] равно dataAll[i] . То же самое происходит внутри $((..)) $(( ${dataAll[$i]} )) равно $(( dataAll[$i] )) или просто $(( dataAll[i] ))
  • Выведите массив на отдельные новые строки с помощью just printf "%sn" "${dataAll[@]}" .
  • Возможно, вы захотите переписать его awk для повышения скорости и эффективности