let num1=3.17648e-22
let num2=1.5
现在,我只想对这两个数字进行简单比较:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
很不幸,我在正确处理num1,可以是“电子格式”。
#1 楼
使用Bash的数字上下文可以更方便地完成此操作:if (( $(echo "$num1 > $num2" |bc -l) )); then
…
fi
解释
通过基本计算器命令
bc
返回1或0。选项
-l
等效于--mathlib
;它会加载标准数学库。将整个表达式括在双括号
(( ))
之间会将这些值分别转换为true或false。请确保
bc
基本计算器包已安装。如果使用大写字母
E
,则这同样适用于科学格式的浮标,例如num1=3.44E6
评论
与stackoverflow.com/questions/8654051/…相同的问题,例如$ echo“ 1.1 + 2e + 02” | bc(standard_in)1:语法错误
– Nemo
16-2-2在10:55
@MohitArora请确保您已安装bc计算器包。
– Serge Stroobandt
17 Mar 28 '17在18:52
我得到一个0:在语句if(($(echo“ $ TOP_PROCESS_PERCENTAGE> $ THRESHOLD” | bc -l))中找不到);然后。
– Stephane
17年8月4日在13:14
对于所有获得“未找到命令”的用户,请记住,您需要将bc放入反引号或$()中,然后放入(())... ...((($(bc -l <<<“ $ a> $ b“)))而不是((bc -l <<<” $ a> $ b“))。
–标准化
18年4月13日在1:13
@Nemo以科学计数法用大写字母E书写数字,所有语法错误都将消失。
– Serge Stroobandt
19年5月19日在7:35
#2 楼
bash仅处理整数数学,但您可以按以下方式使用
bc
命令:$ num1=3.17648E-22
$ num2=1.5
$ echo $num1'>'$num2 | bc -l
0
$ echo $num2'>'$num1 | bc -l
1
请注意,指数符号必须为大写
评论
是的,但是要解决错误的计算,需要使用大写字母“ e”以科学数字符号表示,并使用-l标志对bc编程以进行预定义的数学例程
– alrusdi
2011-12-28 10:24
然后,您应该在答案中指出这一点,而不是仅仅发布一个非常相似的解决方案,而不要提及重要的差异。
–丹尼尔·佩尔森(Daniel Persson)
2011-12-28 10:34
这不是一个非常相似的解决方案。 Alrusdi的解决方案使用了bc工具,这就是我向任何BASH程序员推荐的方法。 BASH是无类型语言。是的,它可以执行整数运算,但是对于浮点数,您必须使用一些外部工具。 BC是最好的,因为这就是它的目的。
– DejanLekic
2011-12-28 14:42
因为他试图在if语句中使用它,所以我会证明这一点。如果[$(... | bc -l)== 1];然后 ...
–罗伯特·雅各布斯
15年3月3日在22:12
#3 楼
最好对非整数数学使用awk
。您可以使用以下bash实用程序功能:numCompare() {
awk -v n1="" -v n2="" 'BEGIN {printf "%s " (n1<n2?"<":">=") " %s\n", n1, n2}'
}
,并将其命名为:
numCompare 5.65 3.14e-22
5.65 >= 3.14e-22
numCompare 5.65e-23 3.14e-22
5.65e-23 < 3.14e-22
numCompare 3.145678 3.145679
3.145678 < 3.145679
评论
我喜欢这个答案,人们倾向于回避awk esp初学者,他们似乎认为比实际困难得多,我认为人们被花括号和看似语言混合的语法所吓倒。而且由于几乎可以保证awk也将出现在目标系统上,就像bc一样(不确定是否安装了哪一个)。我喜欢bash脚本,但是没有浮点数,甚至没有微不足道的2个小数位(我猜有人可以为此写一个“假”包装器),真的很烦人...
– osirisgothra
13年11月6日在11:03
自古以来,在shell脚本中使用awk和bc是一种标准做法,我想说一些功能从未添加到shell中,因为它们在awk,bc和其他Unix工具中可用。 Shell脚本中无需纯洁。
– Piokuc
2014年9月15日上午10:06
@WanderingMind这样做的一种方法是传递0或1退出,以便Awk以正确的,机器可读的方式将结果传递回Shell。如果awk -v n1 =“ 123.456” -v n2 =“ 3.14159e17”'BEGIN {退出(n1 <= n2)}'/ dev / null;然后回声更大;否则不回声; fi ...尽管请注意条件是如何反转的(退出状态0表示shell成功)。
–tripleee
16年8月12日在5:13
人们在考虑这个答案,请帮自己一个忙,不要打扰awk。如果您认为awk是答案,请直接使用内嵌python来完成。您的同事和未来的自我将感谢您。
– CivFan
17年7月19日在14:56
为什么只是python。默认情况下,您已经在许多Linux / Unix系统上安装了perl。
– anubhava
17年7月19日在15:44
#4 楼
用于比较没有指数符号,前导或尾随零的浮点数的纯bash解决方案:if [ ${FOO%.*} -eq ${BAR%.*} ] && [ ${FOO#*.} \> ${BAR#*.} ] || [ ${FOO%.*} -gt ${BAR%.*} ]; then
echo "${FOO} > ${BAR}";
else
echo "${FOO} <= ${BAR}";
fi
逻辑运算符的顺序很重要。将整数部分作为数字进行比较,并将小数部分作为字符串进行有意比较。使用此方法将变量分为整数部分和小数部分。
不会将浮点数与整数(不带点)进行比较。
#5 楼
如果满足以下条件,则可以将awk与bash结合使用:if awk 'BEGIN {exit !('$d1' >= '$d2')}'; then
echo "yes"
else
echo "no"
fi
评论
使用awk很棒,因为它可以处理浮点数,但是我个人更喜欢synthax if(($(echo $ d1 $ d2 | awk'{if($ 1> $ 2)print 1;}')))));;然后回声“是”;否则回声“否”;科幻
–David Georg Reichelt
7月13日13:04
该功能无法正常运行。无论如何,Awk都以0状态退出。用exit替换print,就可以了。
–奥修斯
8月28日14:40
@Otheus您需要用exit!替换它,否则它将返回相反的结果。我适当地编辑了答案。
– mgutt
10月13日21:47
#6 楼
当比较软件包版本号时要当心,例如检查grep 2.20是否大于2.6版本:$ awk 'BEGIN { print (2.20 >= 2.6) ? "YES" : "NO" }'
NO
$ awk 'BEGIN { print (2.2 >= 2.6) ? "YES" : "NO" }'
NO
$ awk 'BEGIN { print (2.60 == 2.6) ? "YES" : "NO" }'
YES
我用这样的shell / awk函数解决了这样的问题:
# get version of GNU tool
toolversion() {
local prog="" operator="" value="" version
version=$($prog --version | awk '{print $NF; exit}')
awk -vv1="$version" -vv2="$value" 'BEGIN {
split(v1, a, /\./); split(v2, b, /\./);
if (a[1] == b[1]) {
exit (a[2] '$operator' b[2]) ? 0 : 1
}
else {
exit (a[1] '$operator' b[1]) ? 0 : 1
}
}'
}
if toolversion grep '>=' 2.6; then
# do something awesome
fi
评论
在基于Debian的系统上,dpkg --compare-versions通常很有用。它具有比较内置的Debian软件包版本的完整逻辑,这不仅比x.y还复杂。
–尼尔·梅休(Neil Mayhew)
17年12月14日在21:10
#7 楼
当然,如果您不需要真正的浮点算术,只需在美元的值始终总是恰好有两个十进制数字,您可以删除点(有效乘以100)并比较所得的整数。if [[ $((10#${num1/.})) < $((10#${num2/.})) ]]; then
...
这显然需要您确保两个值的小数位数相同。
#8 楼
我从这里使用了答案并将其放在函数中,可以像这样使用它: 。功能:
is_first_floating_number_bigger 1.5 1.2
result="${__FUNCTION_RETURN}"
或带有调试输出的版本:
is_first_floating_number_bigger () {
number1=""
number2=""
[ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
result=$?
if [ "$result" -eq 0 ]; then result=1; else result=0; fi
__FUNCTION_RETURN="${result}"
}
只需将函数保存在单独的
echo $result
文件中,然后像这样包含它:is_first_floating_number_bigger () {
number1=""
number2=""
echo "... is_first_floating_number_bigger: comparing ${number1} with ${number2} (to check if the first one is bigger)"
[ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
result=$?
if [ "$result" -eq 0 ]; then result=1; else result=0; fi
echo "... is_first_floating_number_bigger: result is: ${result}"
if [ "$result" -eq 0 ]; then
echo "... is_first_floating_number_bigger: ${number1} is not bigger than ${number2}"
else
echo "... is_first_floating_number_bigger: ${number1} is bigger than ${number2}"
fi
__FUNCTION_RETURN="${result}"
}
#9 楼
请检查以下经过编辑的代码:-#!/bin/bash
export num1=(3.17648*e-22)
export num2=1.5
st=$((`echo "$num1 < $num2"| bc`))
if [ $st -eq 1 ]
then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
这很好。
#10 楼
我将其发布为https://stackoverflow.com/a/56415379/1745001的答案,因为它作为此问题的副本而被关闭,因此也适用于此:简单明了就使用awk进行计算,因为它是标准的UNIX工具,因此很可能以bc形式出现,并且在语法上更容易使用。对于这个问题:
$ cat tst.sh
#!/bin/bash
num1=3.17648e-22
num2=1.5
awk -v num1="$num1" -v num2="$num2" '
BEGIN {
print "num1", (num1 < num2 ? "<" : ">="), "num2"
}
'
$ ./tst.sh
num1 < num2
以及作为该问题的重复项而关闭的另一个问题:
$ cat tst.sh
#!/bin/bash
read -p "Operator: " operator
read -p "First number: " ch1
read -p "Second number: " ch2
awk -v ch1="$ch1" -v ch2="$ch2" -v op="$operator" '
BEGIN {
if ( ( op == "/" ) && ( ch2 == 0 ) ) {
print "Nope..."
}
else {
print ch1 '"$operator"' ch2
}
}
'
$ ./tst.sh
Operator: /
First number: 4.5
Second number: 2
2.25
$ ./tst.sh
Operator: /
First number: 4.5
Second number: 0
Nope...
评论
@DudiBoy不,它是清晰,简单,可移植的awk代码,或者是非显而易见的,晦涩的,与外壳相关的shell + bc代码。
–埃德·莫顿(Ed Morton)
19年6月2日在16:53
#11 楼
awk
和类似的工具(我在盯着你sed
...)应该归类到旧项目的垃圾箱中,因为每个代码都是用从未读过的语言编写的,因此每个人都不敢碰它的代码。 > 或者您是一个相对罕见的项目,需要优先使用CPU使用率优化而不是代码维护优化...在这种情况下,请继续。
如果不是,为什么不这样做呢?只需使用可读且明确的内容,例如
python
?您的同伴编码者和未来的自己将感谢您。您可以将python
与bash内联使用,就像其他所有命令一样。num1=3.17648E-22
num2=1.5
if python -c "exit(0 if $num1 < $num2 else 1)"; then
echo "yes, $num1 < $num2"
else
echo "no, $num1 >= $num2"
fi
评论
@Witiko我的原始版本有点奇怪。
– CivFan
17-10-16在15:39
更简洁:如果...否则,请使用not(...)而不是0
–尼尔·梅休(Neil Mayhew)
17年12月14日在21:06
如果您将awk和sed(我在看您的CivFan)降级为历史的垃圾箱,则您是糟糕的系统管理员,并且您输入的代码太多。 (而且我喜欢并使用Python,因此并非如此)。 -1用于放错位置的贪睡。在系统领域中,对于那些工具(Python或否)有一个地方。
– Mike S
17年12月14日在21:42
有趣的是,我最终获得了出色的ol'Perl! awk'$ {print $ 5}'ptpd_log_file | perl -ne'$ _> 0.000100 &&打印'> / tmp / outfile。十分简单。每种语言都有其位置。
– Mike S
17年12月14日在22:22
不要让seds语法古怪。与python不同,awk是每个UNIX安装上的强制性实用程序,并且python -c“ import sys; sys.exit(0如果float($ num1)
–埃德·莫顿(Ed Morton)
19年6月2日14:40
#12 楼
一种支持所有可能的表示法的解决方案,包括具有大写和小写指数的科学表示法(例如12.00e4
): if (( $(bc -l <<< "${value1/e/E} < ${value2/e/E}") ))
then
echo "$value1 is below $value2"
fi
#13 楼
该脚本可能会在我检查grails
版本是否大于最低要求的地方提供帮助。希望能帮助到你。 #!/bin/bash
min=1.4
current=`echo $(grails --version | head -n 2 | awk '{print $NF}' | cut -c 1-3)`
if [ 1 -eq `echo "${current} < ${min}" | bc` ]
then
echo "yo, you have older version of grails."
else
echo "Hurray, you have the latest version"
fi
#14 楼
num1=0.555
num2=2.555
if [ `echo "$num1>$num2"|bc` -eq 1 ]; then
echo "$num1 is greater then $num2"
else
echo "$num2 is greater then $num1"
fi
#15 楼
使用korn shell,在bash中,您可能必须分别比较小数部分#!/bin/ksh
X=0.2
Y=0.2
echo $X
echo $Y
if [[ $X -lt $Y ]]
then
echo "X is less than Y"
elif [[ $X -gt $Y ]]
then
echo "X is greater than Y"
elif [[ $X -eq $Y ]]
then
echo "X is equal to Y"
fi
评论
问题是许多发行版都没有安装ksh,并且如果您的脚本将被其他人使用,则它们倾向于不喜欢安装额外的内容,尤其是当它只是应该以bash编写的脚本时-会认为他们不需要另一个shell来执行此操作,这首先破坏了使用bash脚本的全部原因-确保我们也可以在C ++中对其进行编码,但是为什么?
– osirisgothra
13年11月6日上午10:56
没有安装ksh的发行版有哪些?
– Piokuc
2014年9月15日上午10:01
@piokuc,例如Ubuntu Desktop&Server。我会说这是一个很重要的...
–奥利
2014年12月21日上午11:57
另外,问题专门要求在bash中有效的解决方案。可能确实有很好的理由。说,这是大型应用程序的一部分,将所有内容迁移到ksh是不可行的。或者它正在嵌入式平台上运行,而在该平台上确实要安装另一个shell。
–奥利
2014年12月21日12:00
#16 楼
使用具有Java支持的bash突变体bashj(https://sourceforge.net/projects/bashj/),您只需编写(而且易于阅读):#!/usr/bin/bashj
#!java
static int doubleCompare(double a,double b) {return((a>b) ? 1 : (a<b) ? -1 : 0);}
#!bashj
num1=3.17648e-22
num2=1.5
comp=j.doubleCompare($num1,$num2)
if [ $comp == 0 ] ; then echo "Equal" ; fi
if [ $comp == 1 ] ; then echo "$num1 > $num2" ; fi
if [ $comp == -1 ] ; then echo "$num2 > $num1" ; fi
当然bashj bash / java混合提供了更多...
#17 楼
这个怎么样? = DVAL_TO_CHECK="1.00001"
if [ $(awk '{printf( >= ) ? 1 : 0}' <<<" $VAL_TO_CHECK 1 ") -eq 1 ] ; then
echo "$VAL_TO_CHECK >= 1"
else
echo "$VAL_TO_CHECK < 1"
fi
评论
Awk脚本应该简单地退出0来报告真相,退出1来返回false。那么如果awk'BEGIN {exit(ARGV [1]> = ARGV [2])吗? 0:1}'“ $ VAL_TO_CHECK” 1;然后...(如果将Awk脚本封装在shell函数中,则更加优雅)。
–tripleee
17 Dec 8'在10:45
评论
“电子格式”是指指数符号(也称为科学符号)相关:UNIX Shell脚本中的浮点运算