如何在bash或Perl中将一个数字与一个范围进行比较?

7

如何编写一个脚本来比较数字与范围?

1不在2-5之间

或者

3在2-5之间

7个回答

19

Perl6中,它甚至更好。

链式比较运算符:

if( 2 <= $x <= 5 ){
}

智能匹配运算符:

if( $x ~~ 2..5 ){
}

连接点:

if( $x ~~ any 2..5 ){
}

给定 / 当操作符:

given( $x ){
  when 2..5 {
  }
  when 6..10 {
  }
  default{
  }
}

1
给定/当也适用于5.10版本,这是被向后移植到Perl5的其中一件事。 - Brad Gilbert
2
实际上,当 Perl 6 到来时,它将改变你的孙子写代码的方式。 - j_random_hacker
1
@j_random_hacker:“不存在”已经过时了,这是一种恐慌宣传。你可以说“尚未发布”,但它确实存在:http://www.perl.com/download.csp#perl6 - ysth
@ysth:感谢您的指引。看起来Perl 6的进展比我想象的要更快。但是,查看Rakudo功能状态页面:http://www.perlfoundation.org/perl6/index.cgi?rakudo_feature_status 告诉我,除了玩耍之外,事情还不够稳定。 - j_random_hacker
我们开始讨论已经有13年了,但Perl 6仍未发布。我想当@j_random_hacker说它“还不存在”时是正确的。 - Fernando Silveira
显示剩余10条评论

13
在 Perl 中:
if( $x >= lower_limit && $x <= upper_limit ) {
   # $x is in the range
}
else {
   # $x is not in the range
}

感谢您的快速回复! - noobbk
嗯...我认为有些符号缺失了。Perl可能会做正确的事情,但您也需要记住,Perl默认使用浮点数作为数字,因此您可能会遇到0.999999... == 1.0问题。但是我是一名老的Fortran程序员,所以请相应地对我的话打折。 - jaredor
感谢 Brian 的修改。在 Perl 中,看不见的 $ 经常会让我犯错。 - Adnan
@ysth,我认为如果你有"$x = 5;",Perl应该尽可能将其保留为整数,但如果你有"$x = (1/2)*10;",我希望它会被保留为浮点数。除非问题域明确限制为整数,否则浮点问题至少值得考虑。 - jaredor
我几乎想将它标记为Perl5,而不是Perl,但它也能在Perl6上运行。 - Brad Gilbert
显示剩余2条评论

11
在bash中:
$ if [[ 1 -gt 2 && 1 -lt 5 ]]; then echo "true"; fi
$ if [[ 3 -gt 2 && 1 -lt 5 ]]; then echo "true"; fi
true

只是为了好玩:如果 seq $lo $hi | grep -w $num; then echo yes indeedy sir; fi - ysth
3
如果 (( lower <= x && x <= upper )); 那么就输出 true。 - Brad Gilbert

10

智能匹配操作符在 Perl 5.10 中也是可用的:smart match operator

if ( $x ~~ [2..5] ) {
    # do something
}

可以使用List::MoreUtils来完成任何{$_ == $x} 2..5。 - hillu
或者Quantum::Superpositions。但是那些或者L::MU的任何一个都非常昂贵,以至于想到将它们用于琐碎的测试就会让我的过早优化的血液凝结。 - ysth

2
在Bash中:
x=9; p="\<$x\>"; if [[ $(echo {10..20}) =~ $p ]]; then echo true; else echo false; fi

已编辑以正确处理下面评论中提到的条件。

rangecheck () { local p="\<$1\>"; if [[ $(echo {10..20}) =~ $p ]]; then echo true; else echo false; fi; }
for x in {9..21}; do rangecheck "$x"; done
false
true
.
.
.
true
false

失败了,因为 if [[ $(echo {10..20}) =~ 9 ]]; then echo true; fi 返回 true。不过这个想法不错,可以改进一下吗?(我对 Bash 的知识不是很丰富) - sharat87
@ShrikantSharat:我已经编辑了我的答案以纠正那个问题。感谢您指出。 - Dennis Williamson

1

In perl

grep {/^$number$/} (1..25);

如果数字在范围内,将返回真值;否则返回假值。

例如:

[dsm@localhost:~]$ perl -le 'print "has `$ARGV[0]`" if grep {/^$ARGV[0]$/} (1..25)' 4
has `4`
[dsm@localhost:~]$ perl -le 'print "has `$ARGV[0]`" if grep {/^$ARGV[0]$/} (1..25)' 456
[dsm@localhost:~]$ 

“将会给你一个非空列表” - 实际上,当在标量上下文中使用grep(就像在您的示例中一样)时,Perl将返回true/false - 而且较新的Perl也会在这种情况下进行短路处理,如果我没记错的话。 - user55400

1

自Bash 3.0版本开始,[[测试的支持正则表达式。

[[ 3 =~ ^[2-5]$ ]]; echo $? # 0

在测试中,数值比较运算符有时会返回错误,如果输入不是数字:

[[ 1a -ge 1 ]]; echo $? # value too great for base (error token is "1a")
[[ '$0' -le 24 ]] # syntax error: operand expected (error token is "$o")

您可以使用=〜来测试输入是否为整数:
x=a23; [[ "$x" =~ ^[0-9]+$ && "$x" -ge 1 && "$x" -le 24 ]]; echo $? # 1
x=-23; [[ "$x" =~ ^-?[0-9]+$ && "$x" -ge -100 && "$x" -le -20 ]]; echo $? # 0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接