#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
для повышения скорости и эффективности