在bash中将十进制值与最多2个点进行比较
我不熟悉shell脚本。我有十进制数,比如说在bash中将十进制值与最多2个点进行比较,bash,decimal,Bash,Decimal,我不熟悉shell脚本。我有十进制数,比如说[2,1.2,3.2,3.2.2,3.2.3] 这里的最高数字是3.2.3,但我的代码返回3.2。如何比较小数点不超过2的数字 var=3.2.2 var2=3.2.3 这是比较的正确方法吗 if (( $(echo "$var2 > $var" | bc -l) )); 请帮助您需要将这些字符串按“.”(IFS=。)拆分,然后开始比较每个段 您可以在中找到完整的示例,该示例允许您确定: “3.0.4.10>3.0.4.2” “4.08 1
[2,1.2,3.2,3.2.2,3.2.3]
这里的最高数字是3.2.3,但我的代码返回3.2。如何比较小数点不超过2的数字
var=3.2.2
var2=3.2.3
这是比较的正确方法吗
if (( $(echo "$var2 > $var" | bc -l) ));
请帮助您需要将这些字符串按“.”(
IFS=。
)拆分,然后开始比较每个段
您可以在中找到完整的示例,该示例允许您确定:
- “3.0.4.10>3.0.4.2”
- “4.08<4.08.01”
#!/bin/bash
function integerversion ()
{
IFS=. read a b c <<< "$1"
[ -z $b ] && b=0
[ -z $c ] && c=0
echo $((a*10000+b*100+c))
}
# Test it out
[ $(integerversion "3") -gt $(integerversion "2.8") ] && echo "3 > 2.8"
[ $(integerversion "2.2") -gt $(integerversion "1.9") ] && echo "2.2 > 1.9"
[ $(integerversion "0.99") -lt $(integerversion "1.0") ] && echo "0.99 < 1.0"
#/bin/bash
函数integerversion()
{
IFS=.读a b c 2.8
2.2 > 1.9
0.99 < 1.0
您正在寻找的是一个版本的排序,它存在于各种可执行文件中。另一个适合这一要求的工具是排序
。但是,由于您的值包含在变量中,而不是在数字列表中,排序-t:-k 1.1n,2.2n,3.3n文件名
几乎没有用处,除非您想编写va将值输出到临时文件,并对其进行排序,以数组形式返回结果(一个好主意)。尽管如此,您可以根据v1
和v2
实现短排序,以达到以下目的:
#!/bin/bash
[ -n "$1" ] && [ -n "$2" ] || {
printf "Error: insufficient input. Usage: %s ver_num1 ver_num2\n" "${0//*\//}"
exit 1
}
v1="$1" # v1
v2="$2" # v2
v1s=$v1 # saved copies of complete string
v2s=$v2 # (same for v2)
[ "$v1" = "$v2" ] && # test inputs are equal and exit
echo "$v1 = $v2" &&
exit 0
while :; do
tv1=${v1%%.*} # tmpv1 stores the first number for v1
tr1=${v1#*.} # trv1 stores the remaining digits for v1
tv2=${v2%%.*} # (same for v2)
tr2=${v2#*.}
if [ "$tv1" = "" ] || [ "$tv2" = "" ]; then # if different length and
[ -n "$tv1" ] && echo "$v1s > $v2s" && break # equal at this point
[ -n "$tv2" ] && echo "$v1s < $v1s" && break # longer string wins
fi
if [ "$tv1" -gt "$tv2" ]; then # test 1st digit
echo "$v1s > $v2s" && break # if > or <, output results and break
elif [ "$tv1" -lt "$tv2" ]; then
echo "$v1s < $v2s" && break
else # if no determination, go to next digit
v1=$tr1 # set v1, v2 to remaining digits to loop again
v2=$tr2
fi
done
exit 0
!/bin/bash
[-n“$1”]&&&[-n“$2”]||{
printf“错误:输入不足。用法:%s ver\u num1 ver\u num2\n”“${0/*\/}”
出口1
}
v1=“$1”#v1
v2=“$2”#v2
v1s=$v1#保存的完整字符串副本
v2s=$v2#(与v2相同)
[“$v1”=“$v2”]&&测试输入相等并退出
回显“$v1=$v2”&&
出口0
当:;做
tv1=${v1%%.*}#tmpv1存储v1的第一个数字
tr1=${v1}}#trv1存储v1的剩余数字
tv2=${v2%%.*}#(与v2相同)
tr2=${v2#*。}
如果[“$tv1=”]| |[“$tv2=”];那么#如果长度和
[-n“$tv1”]&&echo“$v1s>$v2s”&&break#在这一点上相等
[-n“$tv2”]&&echo“$v1s<$v1s”&&break#更长的字符串获胜
fi
如果[“$tv1”-gt“$tv2”];则#测试第一位数字
回显“$v1s>$v2s”&中断#if>或1.2.4.7
注意:我添加了一些额外的测试,并将要通过的值设置为arg1
和arg2
,让您开始。- 一个简短的纯Bash函数,可以执行您想要的操作,并进行错误检查
- 返回代码:
(成功)如果0
$1在完整版本排序脚本中找到,则返回代码。可能重复
#!/bin/bash [ -n "$1" ] && [ -n "$2" ] || { printf "Error: insufficient input. Usage: %s ver_num1 ver_num2\n" "${0//*\//}" exit 1 } v1="$1" # v1 v2="$2" # v2 v1s=$v1 # saved copies of complete string v2s=$v2 # (same for v2) [ "$v1" = "$v2" ] && # test inputs are equal and exit echo "$v1 = $v2" && exit 0 while :; do tv1=${v1%%.*} # tmpv1 stores the first number for v1 tr1=${v1#*.} # trv1 stores the remaining digits for v1 tv2=${v2%%.*} # (same for v2) tr2=${v2#*.} if [ "$tv1" = "" ] || [ "$tv2" = "" ]; then # if different length and [ -n "$tv1" ] && echo "$v1s > $v2s" && break # equal at this point [ -n "$tv2" ] && echo "$v1s < $v1s" && break # longer string wins fi if [ "$tv1" -gt "$tv2" ]; then # test 1st digit echo "$v1s > $v2s" && break # if > or <, output results and break elif [ "$tv1" -lt "$tv2" ]; then echo "$v1s < $v2s" && break else # if no determination, go to next digit v1=$tr1 # set v1, v2 to remaining digits to loop again v2=$tr2 fi done exit 0
$ bash 3waySort.sh 3.2.2 3.2.3 3.2.2 < 3.2.3 $ bash 3waySort.sh 3.2.3 3.2.3 3.2.3 = 3.2.3 $ bash 3waySort.sh 3.2 3.2.3 3.2 < 3.2.3 $ bash 3waySort.sh 1.2.4.7 3.2.3 3.2.3 > 1.2.4.7
is_lt() { # success if $1<$2 local x y sx sy i IFS=. read -ra x <<< "$1" IFS=. read -ra y <<< "$2" (((sx=${#x[@]})==0 || (sy=${#y[@]})==0)) && return 2 for((i=0;i<sx && i<sy;++i)); do [[ ${x[i]} =~ ^[[:digit:]]+$ && ${y[i]} =~ ^[[:digit:]]+$ ]] || return 2 ((10#${x[i]}<10#${y[i]})) && return 0 ((10#${x[i]}>10#${y[i]})) && return 1 done return $((sx>=sy)) }
$ is_lt 3.2.2 3.2.3; echo $? 0 $ is_lt 3.2.2 3.2.2; echo $? 1 $ is_lt 3.2.2 3.2.2.0; echo $? 0 $ is_lt 3.2.2 3.2.2.1; echo $? 0 $ is_lt 3.1 3.x; echo $? 2 $ # Error doesn't trigger if order could be determined early: $ is_lt 3.2.2 3.2.3.x; echo $? 0 $ is_lt 3.08.09 3.8.10; echo $? 0
var=3.2.2 var2=3.2.3 if is_lt "$var" "$var2"; then echo "it works" else echo "doesn't work" fi