Круглая скобка в expr арифметике: 3 * (2 + 1)

Я не знаком с развертыванием виртуальных серверов Ubuntu, но я развернул виртуальные серверы CentOS с помощью запускать сценария от веб-сервера Сапожника. Завихрение установок сценария, и затем это использует завихрение для "проверения с помощью ping-запросов" URL (уникальный для каждой машины) на веб-сервере после каждого этапа установки.

Я не знаком с Бродягой, но я предполагаю, что это имеет подобные функции.

63
30.06.2016, 03:11
6 ответов

Вы можете использовать SED :

sed -e 's/[0-9]*=/=/' < data

Это заменяет ( S ) любой текст, который является ноль или более символов в диапазоне 0-9 с последующим = знак только с = знак.

-121--202702-

Другим способом использования Пусть Bash встроена:

$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9

Примечание

AS @ Stéphane Chazelas указал , в Bash Вы должны использовать ((...)) , чтобы сделать арифметику в течение EXPR или , пусть для разборчивости.

Для переносимости, используйте $ ((...)) , как @Bernhard Answer .

41
27.01.2020, 19:32

Нет причин использовать expr для арифметики в современных оболочках.

POSIX определяет оператор расширения $((...)). Таким образом, вы можете использовать его во всех POSIX-совместимых оболочках (sh всех современных Unix-ликов, тире, баше, яше, мкш, zsh, шиш, кш...).

a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))

ksh также ввел let builtin, который передается в том же виде арифметического выражения, не расширяется во что-то, а возвращает статус выхода, основанный на том, разрешается выражение на 0 или нет, как в expr:

if let 'a = 3 * (2 + 1)'; then
  echo "$a is non-zero"
fi

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

if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
  echo "$a is non-zero and 3 > 1"
fi
((a+=2))

, которая намного более понятна и должна быть использована вместо нее.

let и (((...)) доступны только в ksh, zsh и bash. Синтаксис $((...)) должен быть предпочтительным, если требуется переносимость на другие оболочки, expr нужен только для оболочек, похожих на оболочку Борна до POSIX (обычно это оболочка Борна или ранние версии оболочки Альмквиста).

На не Борновском фронте есть несколько оболочек со встроенным арифметическим оператором:

  • csh/tcsh (на самом деле первая оболочка Unix со встроенной арифметической оценкой):

    @ a = 3 * (2 + 1)
    
  • akanga (на основе rc)

    a = $:'3 * (2 + 1)'.
    
  • в качестве примечания к истории, первоначальная версия оболочки Альмквиста, размещенная на usenet в 1989 году, имела expr сборку (на самом деле объединенную с test), но была удалена позже.

40
27.01.2020, 19:32

Вместо этого можно использовать арифметическое расширение.

echo "$(( 3 * ( 2 + 1 ) ))"
9

По моему личному мнению, это выглядит немного лучше, чем использование expr.

Из man bash

Arithmetic Expansion Арифметическое расширение позволяет оценить арифметическое выражение и подставить результат. Формат арифметического расширения:

 $((expression))

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

Оценка выполняется по правилам, перечисленным ниже в разделе Арифметическая оценка. Если выражение является недействительным, bash печатает сообщение, указывающее на неудачу, и замена не происходит.

78
27.01.2020, 19:32

expr - это внешняя команда, это не специальный синтаксис оболочки. Поэтому, если вы хотите, чтобы expr увидел специальные символы оболочки, вам нужно защитить их от разбора оболочки, заключив их в кавычки. Более того, expr требует, чтобы каждое число и оператор передавались как отдельный параметр. Таким образом:

expr 3 \* \( 2 + 1 \)

если вы не работаете на старинной уникальной системе 1970х или 1980х годов, то очень мало причин использовать expr. В старые времена в оболочках не было встроенного способа выполнения арифметики, и вам приходилось вызывать утилиту expr. Все POSIX-оболочки имеют встроенную арифметику с помощью синтаксиса арифметического расширения.

echo "$((3 * (2 + 1)))"

Конструкция $((...)) расширяется до результата арифметического выражения (записанного в десятичном виде). Bash, как и большинство оболочек, поддерживает только целочисленный арифметический модуль 264 (или модуль 232 для старых версий bash и некоторых других оболочек на 32-битных машинах).

Bash предлагает дополнительный удобный синтаксис, когда вы хотите выполнить присваивание или проверить, является ли выражение 0, но не заботитесь о результате. Эта конструкция также существует в ksh и zsh, но не в обычном sh.

((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then …

В дополнение к целочисленной арифметике, expr предлагает несколько функций манипулирования строками. Они также подразделяются на возможности POSIX-оболочек, за исключением одной: expr STRING : REGEXP проверяет, соответствует ли строка указанному регеxp. POSIX-оболочка не может сделать это без внешних утилит, но bash может с помощью [[ STRING =~ REGEXP ]] различным синтаксисом регенерации - expr является классическим инструментом и использует BRE, bash использует ERE).

Если вы не работаете со скриптами, работающими на системах 20-летней давности, вам не нужно знать, что expr когда-либо существовал. Используйте арифметику оболочек.

17
27.01.2020, 19:32

Используйте скобки с кавычками:

expr 3 '*' '(' 2 '+' 1 ')'
9

Квоты предотвращают интерпретацию бэша как синтаксиса бэша.

13
27.01.2020, 19:32

Если у вас есть bc.

echo '3 * (2 + 1)'|bc 
9                                                                    
2
20.08.2021, 12:47

Теги

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