У меня есть это bash script, и у меня была проблема в строке 16.
Как я могу взять предыдущий результат строки 15 и добавить
это переменной в строке 16?
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in `ls output-$i-*`; do
echo "$j"
metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
num= $num + $metab (line16)
done
echo "$num"
done
Ответ 1
Для целых чисел:
-
Используйте арифметическое расширение: $((EXPR))
num=$((num1 + num2))
num=$(($num1 + $num2)) # also works
num=$((num1 + 2 + 3)) # ...
num=$[num1+num2] # old, deprecated arithmetic expression syntax
-
Использование внешней утилиты expr
. Обратите внимание, что это необходимо только для действительно старых систем.
num=`expr $num1 + $num2` # whitespace for expr is important
Для плавающей запятой:
Bash не поддерживает это напрямую, но есть несколько внешних инструментов, которые вы можете использовать:
num=$(awk "BEGIN {print $num1+$num2; exit}")
num=$(python -c "print $num1+$num2")
num=$(perl -e "print $num1+$num2")
num=$(echo $num1 + $num2 | bc) # whitespace for echo is important
Вы также можете использовать научную нотацию (например: 2.5e+2
)
Общие ошибки:
-
При установке переменной вы не можете иметь пробелы по обе стороны от =
, иначе это заставит оболочку интерпретировать первое слово как имя запускаемого приложения (например: num=
или num
)
num= 1
num =2
-
bc
и expr
ожидают, что каждый номер и оператор являются отдельным аргументом, поэтому важны пробелы. Они не могут обрабатывать аргументы типа 3+
+4
.
num=`expr $num1+ $num2`
удаp >
Ответ 2
Используйте арифметическое расширение $(( ))
.
num=$(( $num + $metab ))
Подробнее см. http://tldp.org/LDP/abs/html/arithexp.html.
Ответ 3
Есть тысячи способов сделать это. Здесь используется dc
:
dc <<<"$num1 $num2 + p"
Но если это тоже bash -y для вас (или важности переносимости), вы можете сказать
echo $num1 $num2 + p | dc
Но, может быть, вы один из тех людей, которые думают, что RPN icky и weird; не беспокойтесь! bc
здесь для вас:
bc <<< "$num1 + $num2"
echo $num1 + $num2 | bc
Тем не менее, есть некоторые несвязанные улучшения, которые вы могли бы внести в свой script
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in output-$i-* ; do # for can glob directly, no need to ls
echo "$j"
# grep can read files, no need to use cat
metab=$(grep EndBuffer "$j" | awk '{sum+=$2} END { print sum/120}')
num=$(( $num + $metab ))
done
echo "$num"
done
EDIT:
Как описано в BASH FAQ 022, bash не поддерживает номера с плавающей запятой. Если вам нужно суммировать числа с плавающей запятой, необходимо использовать внешний инструмент (например, bc
или dc
).
В этом случае решение будет
num=$(dc <<<"$num $metab + p")
Чтобы добавить скользящие числа с плавающей точкой в num
.
Ответ 4
В bash,
num=5
x=6
(( num += x ))
echo $num # ==> 11
Обратите внимание, что bash может обрабатывать только целочисленную арифметику, поэтому, если ваша команда awk возвращает дробь, тогда вы захотите перепроектировать: здесь ваш код переписан немного, чтобы выполнить всю математику в awk.
num=0
for ((i=1; i<=2; i++)); do
for j in output-$i-*; do
echo "$j"
num=$(
awk -v n="$num" '
/EndBuffer/ {sum += $2}
END {print n + (sum/120)}
' "$j"
)
done
echo "$num"
done
Ответ 5
Мне тоже нравится этот метод, меньше беспорядка:
count=$[count+1]
Ответ 6
Я всегда забываю синтаксис, поэтому я прихожу к google, но тогда я никогда не нахожу тот, с которым я знаком: P. Это самый чистый для меня и более верный тому, что я ожидал бы на других языках.
i=0
((i++))
echo $i;
Ответ 7
#!/bin/bash
read X
read Y
echo "$(($X+$Y))"
Ответ 8
Вы должны объявить метам как целое, а затем использовать арифметическую оценку
declare -i metab num
...
num+=metab
...
Для получения дополнительной информации см. https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html#Shell-Arithmetic
Ответ 9
Другой переносимый POSIX
способ выполнения в bash
, который можно определить как функцию в .bashrc
для всех удобных арифметических операторов.
addNumbers () {
local IFS='+'
printf "%s\n" "$(( $* ))"
}
и просто вызовите его в командной строке как,
addNumbers 1 2 3 4 5 100
115
Идея состоит в том, чтобы использовать Input-Field-Separator (IFS), специальную переменную в bash
, используемую для разделения слов после расширение и разделение строк на слова. Функция меняет значение локально, чтобы использовать слово-расщепляющий символ в качестве оператора суммы +
.
Помните, что IFS
изменен локально и не влияет на поведение по умолчанию IFS
по умолчанию вне области действия. Выдержка из страницы man bash
,
Оболочка рассматривает каждый символ IFS как разделитель и разбивает результаты других расширений на слова на этих символах. Если IFS не задано, или его значение в точности, значение по умолчанию, а затем последовательности из, и в начале и конце результатов предыдущих расширений игнорируются, и любая последовательность символов IFS не в начале и конце служит для разграничения слова.
"$(( $* ))"
представляет список аргументов, передаваемых для разделения на +
, а затем значение суммы выводится с использованием функции printf
. Функция может быть расширена, чтобы добавить область для других арифметических операций.