2015-07-30 4 views
1

Скажут, у нас есть массив BASH с целыми числами:Арифметические операции на все элементы в массиве BASH

declare -a arr=(1 2 3) 

, и я хочу сделать арифметическую операцию на каждый элемент, например, добавить 1. Есть ли к заселение вместо себя иного цикл:

for ((i=0 ; i<=${#arr[@]}-1 ; i++)) ; do 
    arr[$i]=$((${arr[$i]} + 1)) 
done 

Я попробовал несколько вариантов:

arr=$((${arr[@]} + 1)) 

терпит неудачу, в то время как

arr=$(($arr + 1)) 

приводит

echo ${arr[@]} 
2 2 3 

Таким образом, только первый (нулевой) элемент изменен.

Я читал о решениях awk, но хотел бы знать, поддерживает ли BASH-арифметику такие пакетные операции для каждого элемента массива.

+2

Я не думаю, что есть альтернатива. Как замечание, ни один из языков программирования, которые я использую, не может сделать это изначально. Кроме того, вы можете упростить 'arr [$ i] = $ (($ {arr [$ i]} + 1))' to 'arr [$ i] ++' – Aserre

+1

Я не знаю о ваших предпочтительных языках, но, например, FORTRAN поддерживает 'arr (:) = arr (:) + 1' или' arr3 (:) = arr1 (:) * arr2 (:) ', поэтому у меня была надежда, что BASH будет способен. Извините, я не могу воспроизвести 'arr [$ i] ++' вещь. Позаботьтесь об этом? – Fiximan

+1

забыли скобки. Правильный синтаксис - '(($ arr [$ i] ++))' – Aserre

ответ

1

Я знаю, что ваш вопрос не свежий, но вы можете сделать то, что вы хотите, объявив свой массив как integer, а затем применяя замену:

declare -ia arr=(1 2 3) 
value=1 

declare -ia 'arr_added=("${arr[@]/%/+$value}")' 
echo "arr_added: ${arr_added[*]}" 

value=42 
declare -ia 'arr_added=("${arr[@]/%/+$value}")' 
echo "arr_added: ${arr_added[*]}" 

Он выводит:

arr_added: 2 3 4 
arr_added: 43 44 45 

Вы можете выполнять другие математические операции, а также:

value=3 
declare -ia 'arr_multd=("${arr[@]/%/*$value}")' 
echo "arr_multd: ${arr_multd[*]}" 

Выходы:

arr_multd: 3 6 9 
+1

Спасибо - в моих тестах также работает без использования кавычек, например, 'declare -ia new_arr = ($ {arr [@]} /%/+ $ value}'. Есть ли какая-либо документация по этому поводу? см. его в 'man bash'. – Fiximan

+0

Да, в документации массива' -i' нет прямого упоминания ни на какой странице, ни на TLDP, ни на подобном.Вы можете проверить '-i', хотя в разделе« Ввод переменных: declare или typeset »[http://tldp.org/LDP/abs/html/declareref.html]. Он работает для любой переменной, включая массивы. – j4x

-1

вы можете использовать Eval, чтобы иметь чувство лямбда-функции (не уверен о синтаксисе, но это должно быть главной идеей):

eval "function add1 { x=$1; y=$((x+1)) ; return $y; }" 
for ((i=0 ; i<=${#arr[@]}-1 ; i++)) ; do 
    add1 ${arr[i]} 
done 
+1

Я не думаю, что это отвечает на вопрос. OP хочет избежать цикла for вообще – Aserre

+0

Это также бессмысленное использование 'eval', так как разложения параметров будут расширены до того, как функция будет определена. 'return' используется для возврата статуса выхода, а не вычисления. – chepner

 Смежные вопросы

  • Нет связанных вопросов^_^