Если заявление 3 условия Bash - PullRequest
0 голосов
/ 03 июля 2018

Я хочу сделать оператор if с тремя условиями, которые должны быть выполнены одновременно. Я использую Ubuntu Bash для Windows, и значения $ c1, $ c2 и $ c3 нецелые (десятичные отрицательные числа).

if [ (( $(echo "$c1 < 0" | bc -l) )) ]  && [ (( $(echo "$c2 < 0" | bc -l) )) ] && [ (( $(echo "$c3 < 0" | bc -l) )) ];
    then
      >&2 echo -e "   ++ Constraints OK"

else
      >&2 echo -e "   ++ Constraints WRONG"

fi

Однако в строке if появляется следующая синтаксическая ошибка: syntax error near unexpected token `('

Если я просто поставлю одно условие:

if (( $(echo "$c1 < 0" | bc -l) )); 

это работает, но когда я добавляю три из них как AND (&&), я получаю ошибку. Кто-нибудь может мне помочь?

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Сначала передайте реляционные операторы AND в bc, чтобы избавиться от пунктуации (также только один раз вызывает bc):

if (( $(echo "$c1 < 0 && $c2 < 0 && $c3 < 0" | bc -l) == 1 ))
then
    >&2 echo -e "   ++ Constraints OK"
else
    >&2 echo -e "   ++ Constraints WRONG"
fi

Хотя, если бы это был я, я бы создал функцию оболочки, возвращающую «истинное» состояние выхода, если bc оценивает результат выражения как ненулевой. Тогда вы можете скрыть большую часть уродливой пунктуации в одном месте, отделенном от вашей основной логики:

function bc_true() {
    (( $(echo "$@" | bc -l) != 0 ))
}

И напишите (IMO) чистое выражение оболочки:

if bc_true "$c1 < 0 && $c2 < 0 && $c3 < 0"
then
    ...
0 голосов
/ 03 июля 2018

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

if [[ $c1 = -* ]] && [[ $c2 = -* ]] && [[ $c3 = -* ]]; then
      >&2 echo "   ++ Constraints OK"
else
      >&2 echo "   ++ Constraints WRONG"
fi

Если вы хотите более конкретно определить допустимые форматы (f / e, допуская начальные пробелы), регулярное выражение является еще одним вариантом, который аналогичным образом может быть реализован более эффективно, чем порождение серии подоболочек, вызывающих bc:

nnum_re='^[[:space:]]*-([[:digit:]]*[.][[:digit:]]+|[[:digit:]]+)$'
if [[ $c1 =~ $nnum_re ]] && [[ $c2 =~ $nnum_re ]] && [[ $c3 =~ $nnum_re ]]; then
      >&2 echo "   ++ Constraints OK"
else
      >&2 echo "   ++ Constraints WRONG"
fi
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...