Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash if语句中包含算术、比较和正则运算符的多个条件_Bash_Shell_If Statement_Scripting - Fatal编程技术网

Bash if语句中包含算术、比较和正则运算符的多个条件

Bash if语句中包含算术、比较和正则运算符的多个条件,bash,shell,if-statement,scripting,Bash,Shell,If Statement,Scripting,我试图编写一个脚本,读取三个整数,然后检查其中任何两个数的和是否大于第三个数。如果这是真的,那么它会检查这些数字是否相等,并打印一条消息。如果不是,它将检查任意两个数字是否相等,并打印另一条消息。如果以上所有内容均为假,则会打印一条消息,说明所有数字都不同。 我已尝试将其放在以下嵌套条件中: read X read Y read Z if [ $X + $Y > $Z ] && [ $X + $Z > $Y ] && [ $Y + $Z > $X

我试图编写一个脚本,读取三个整数,然后检查其中任何两个数的和是否大于第三个数。如果这是真的,那么它会检查这些数字是否相等,并打印一条消息。如果不是,它将检查任意两个数字是否相等,并打印另一条消息。如果以上所有内容均为假,则会打印一条消息,说明所有数字都不同。 我已尝试将其放在以下嵌套条件中:

read X
read Y
read Z
if [ $X + $Y > $Z ] && [ $X + $Z > $Y ] && [ $Y + $Z > $X ]
then
    if [ $X = $Y = $Z ]
    then
        echo "All numbers are equal."
    elif [ [ $X = $Y ] && [ $X != $Z ] ] || [ [ $X = $Z ] && [ $X != $Y ] ] || [ [ $Z = $Y ] && [ $X != $Y ] ]
    then
        echo "Two of the numbers are equal."
    else
        echo "None of the numbers is equal to another."
    fi
fi
我已经尝试了所有类型的括号和括号的组合(上面只是其中之一),但到目前为止没有一种有效。 我已经看了相关帖子:

但我还没有发现任何包含算术运算符的覆盖条件。 有人能告诉我什么是正确的方法吗


(编辑:我忘了在原来的帖子中提到我是bash新手,所以请原谅我可能犯的任何严重错误。我仍在试图弄清楚事情是如何运作的。)

以下是伊尼安答案的一个变体,它利用了不需要
$
扩展变量的算术运算,它们接受逻辑运算符,并且第一个测试所有数字是否相等的事实允许简化下面的测试

请注意,检查读取的值是否为整数是避免意外行为的好方法

#!/bin/bash
read X
read Y
read Z
if
  (( X+Y>Z || X+Z>Y || Y+Z>X ))
then
  if
    (( X==Y && Y==Z ))
  then
      echo "All numbers are equal"
  elif
    (( X==Y || X==Z || Z==Y ))
  then
    echo "Two of the numbers are equal"
  else
    echo "All three numbers are different"
  fi
fi
算术表达式的$(())将展开为内部表达式的求值结果。如果表达式是一个导致“true”值的测试,或者如果其计算结果为非零值,则for的
(())
用作返回0的命令,否则返回非零值。第二种形式对于测试非常有用


另外,我喜欢使用
(())
的属性来处理脚本中的开/关选项。例如,
((state_variable))
将在变量为null或0时计算为“false”,否则计算为“true”,这很好地反映了这样一个变量在直觉上的行为方式。

以下是Inian答案的一个变体,它利用了不需要
$
展开变量的算术运算,它们接受逻辑运算符,并且第一个关于所有数字相等的测试允许简化以下测试

请注意,检查读取的值是否为整数是避免意外行为的好方法

#!/bin/bash
read X
read Y
read Z
if
  (( X+Y>Z || X+Z>Y || Y+Z>X ))
then
  if
    (( X==Y && Y==Z ))
  then
      echo "All numbers are equal"
  elif
    (( X==Y || X==Z || Z==Y ))
  then
    echo "Two of the numbers are equal"
  else
    echo "All three numbers are different"
  fi
fi
算术表达式的$(())将展开为内部表达式的求值结果。如果表达式是一个导致“true”值的测试,或者如果其计算结果为非零值,则for的
(())
用作返回0的命令,否则返回非零值。第二种形式对于测试非常有用


另外,我喜欢使用
(())
的属性来处理脚本中的开/关选项。例如,
((state_variable))
将在变量为null或0时计算为“false”,否则计算为“true”,这很好地反映了这样一个变量在直觉上的行为方式。

您也可以通过增加匹配项和使用case语句来使用不同的方法

应该更容易用更多的变量进行缩放

#!/bin/bash

read X
read Y
read Z

((Matches+=(X==Y)))
((Matches+=(Y==Z)))
((Matches+=(X==Z)))

case "$Matches" in

0) echo "None of the numbers is equal to another.";;
1) echo "Two of the numbers are equal.";;
3) echo "All numbers are equal.";;

esac

您也可以通过增加匹配项并使用case语句来使用不同的方法

应该更容易用更多的变量进行缩放

#!/bin/bash

read X
read Y
read Z

((Matches+=(X==Y)))
((Matches+=(Y==Z)))
((Matches+=(X==Z)))

case "$Matches" in

0) echo "None of the numbers is equal to another.";;
1) echo "Two of the numbers are equal.";;
3) echo "All numbers are equal.";;

esac

一种完全不同的解决问题的方法

#!/bin/bash

declare -A a               # declare associative array a

read x; a[$x]=$x
read x; a[$x]=$x
read x; a[$x]=$x

case ${#a[@]} in
  1) echo "All numbers are equal." ;;
  2) echo "Two of the numbers are equal." ;;
  3) echo "None of the numbers is equal to another." ;;
esac

一种完全不同的解决问题的方法

#!/bin/bash

declare -A a               # declare associative array a

read x; a[$x]=$x
read x; a[$x]=$x
read x; a[$x]=$x

case ${#a[@]} in
  1) echo "All numbers are equal." ;;
  2) echo "Two of the numbers are equal." ;;
  3) echo "None of the numbers is equal to another." ;;
esac

一个线性函数,浓缩自:

显示所有三种情况:

3a 1 1 1 ; 3a 1 1 2 ; 3a 1 2 3
All numbers are equal.
Two numbers are equal.
No numbers are equal.

一个线性函数,浓缩自:

显示所有三种情况:

3a 1 1 1 ; 3a 1 1 2 ; 3a 1 2 3
All numbers are equal.
Two numbers are equal.
No numbers are equal.

请参阅:
帮助测试
[…]
测试内置的同义词。您在第一个
中意识到,如果
只需检查两个大于另一个的数字一次,您不需要检查每个组合。@123是的,您是对的,但我想在某一点之后,我更感兴趣的是找出这样的条件是否可行以及如何实现。请参阅:
help test
[…]
测试内置的同义词。您在第一个
中意识到,如果
只需检查两个大于另一个的数字一次,您不需要检查每个组合。@123是的,您是对的,但我想在某一点之后,我更感兴趣的是找出这样的条件是否可行以及如何实现。这是OP尝试的一个很好的简化,在我的答案中尝试坚持OP的逻辑,但这看起来很简洁
++
你和@Inian都理解我的想法,但你离我最初打算做的有点近。我想我混合了
(())
[[]]
这两种语法。请您再解释一下您在代码后的第一段中描述的内容,
(())
的作用是什么?所以,如果我理解正确的话,如果它的计算结果为非零值,则返回0;如果它的计算结果为0,则返回非零数?再次感谢您的帮助。@Ioannis
(())
在计算为一个数字时会按照您所说的做,但如果它包含一个测试(即
=
!=
@Ioannis请注意,
(())
可以用于赋值,因此它可能会产生副作用(与
[[]]]]
相反)。赋值的形式为
((varname=value))
。相等性测试为
=
(与
[[]]
相反,后者接受
=
=
来测试相等性),因此,如果你不经常使用它,可能会有点混淆。这是OP尝试的一个很好的简化,在我的答案中尝试坚持OP的逻辑,但是